Commit afa85a3b authored by Weihang Li's avatar Weihang Li Committed by Zheng Zengkai
Browse files

RDMA/hns: Use refcount_t instead of atomic_t for CQ reference counting

mainline inclusion
from mainline-v5.12-rc1
commit cc9e5a84
category: bugfix
bugzilla: 174002
CVE:NA

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

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

The refcount_t API will WARN on underflow and overflow of a reference
counter, and avoid use-after-free risks.

Link: https://lore.kernel.org/r/1622194663-2383-9-git-send-email-liweihang@huawei.com


Signed-off-by: default avatarWeihang Li <liweihang@huawei.com>
Signed-off-by: default avatarJason Gunthorpe <jgg@nvidia.com>
Signed-off-by: default avatarwangsirong <wangsirong@huawei.com>
Reviewed-by: default avatarChunZhi Hu <huchunzhi@huawei.com>
Signed-off-by: default avatarZheng Zengkai <zhengzengkai@huawei.com>
parent bf20d250
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -154,7 +154,7 @@ static int alloc_cqc(struct hns_roce_dev *hr_dev, struct hns_roce_cq *hr_cq)
	hr_cq->cons_index = 0;
	hr_cq->arm_sn = 1;

	atomic_set(&hr_cq->refcount, 1);
	refcount_set(&hr_cq->refcount, 1);
	init_completion(&hr_cq->free);

	return 0;
@@ -188,7 +188,7 @@ static void free_cqc(struct hns_roce_dev *hr_dev, struct hns_roce_cq *hr_cq)
	synchronize_irq(hr_dev->eq_table.eq[hr_cq->vector].irq);

	/* wait for all interrupt processed */
	if (atomic_dec_and_test(&hr_cq->refcount))
	if (refcount_dec_and_test(&hr_cq->refcount))
		complete(&hr_cq->free);
	wait_for_completion(&hr_cq->free);

@@ -481,7 +481,7 @@ void hns_roce_cq_event(struct hns_roce_dev *hr_dev, u32 cqn, int event_type)
		return;
	}

	atomic_inc(&hr_cq->refcount);
	refcount_inc(&hr_cq->refcount);

	ibcq = &hr_cq->ib_cq;
	if (ibcq->event_handler) {
@@ -491,7 +491,7 @@ void hns_roce_cq_event(struct hns_roce_dev *hr_dev, u32 cqn, int event_type)
		ibcq->event_handler(&event, ibcq->cq_context);
	}

	if (atomic_dec_and_test(&hr_cq->refcount))
	if (refcount_dec_and_test(&hr_cq->refcount))
		complete(&hr_cq->free);
}

+1 −1
Original line number Diff line number Diff line
@@ -444,7 +444,7 @@ struct hns_roce_cq {
	int				cqe_size;
	unsigned long			cqn;
	u32				vector;
	atomic_t			refcount;
	refcount_t			refcount;
	struct completion		free;
	struct list_head		sq_list; /* all qps on this send cq */
	struct list_head		rq_list; /* all qps on this recv cq */