Commit ddb4372e authored by Chengchang Tang's avatar Chengchang Tang Committed by Juan Zhou
Browse files

RDMA/hns: Fix deadlock on SRQ async events.

maillist inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I9HASN
CVE: NA

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=b46494b6f9c19f141114a57729e198698f40af37



----------------------------------------------------------------------

xa_lock for SRQ table may be required in AEQ. Use xa_store_irq()/
xa_erase_irq() to avoid deadlock.

Fixes: 81fce629 ("RDMA/hns: Add SRQ asynchronous event support")
Signed-off-by: default avatarChengchang Tang <tangchengchang@huawei.com>
Signed-off-by: default avatarJunxian Huang <huangjunxian6@hisilicon.com>
Link: https://lore.kernel.org/r/20240412091616.370789-5-huangjunxian6@hisilicon.com


Signed-off-by: default avatarLeon Romanovsky <leon@kernel.org>
Signed-off-by: default avatarJuan Zhou <zhoujuan51@h-partners.com>
parent bed65a51
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -122,7 +122,7 @@ static int alloc_srqc(struct hns_roce_dev *hr_dev, struct hns_roce_srq *srq)
		return ret;
	}

	ret = xa_err(xa_store(&srq_table->xa, srq->srqn, srq, GFP_KERNEL));
	ret = xa_err(xa_store_irq(&srq_table->xa, srq->srqn, srq, GFP_KERNEL));
	if (ret) {
		ibdev_err(ibdev, "failed to store SRQC, ret = %d.\n", ret);
		goto err_put;
@@ -135,7 +135,7 @@ static int alloc_srqc(struct hns_roce_dev *hr_dev, struct hns_roce_srq *srq)
	return 0;

err_xa:
	xa_erase(&srq_table->xa, srq->srqn);
	xa_erase_irq(&srq_table->xa, srq->srqn);
err_put:
	hns_roce_table_put(hr_dev, &srq_table->table, srq->srqn);

@@ -156,7 +156,7 @@ static void free_srqc(struct hns_roce_dev *hr_dev, struct hns_roce_srq *srq)
	if (ret == -EBUSY)
		srq->delayed_destroy_flag = true;

	xa_erase(&srq_table->xa, srq->srqn);
	xa_erase_irq(&srq_table->xa, srq->srqn);

	if (refcount_dec_and_test(&srq->refcount))
		complete(&srq->free);