Linux RDMA and InfiniBand development
 help / color / mirror / Atom feed
* [PATCH rdma-rc v2 00/15] RDMA/bnxt_re: Generic driver fixes
@ 2026-06-15 22:47 Selvin Xavier
  2026-06-15 22:47 ` [PATCH rdma-rc v2 01/15] RDMA/bnxt_re: Initialize dpi variable to zero Selvin Xavier
                   ` (14 more replies)
  0 siblings, 15 replies; 16+ messages in thread
From: Selvin Xavier @ 2026-06-15 22:47 UTC (permalink / raw)
  To: leon, jgg
  Cc: linux-rdma, andrew.gospodarek, kalesh-anakkur.purayil,
	sriharsha.basavapatna, Selvin Xavier

Includes fixes for few issues pointed by sashiko. Also, some
generic fixes found during internal code reviews.

Please review and Apply.

Thanks,
Selvin Xavier

v1 -> v2:
  - Added patches for SRQ/CQ resource teardown in HW before freeing the
    toggle page to avoid any access from NQ processing after the page is
    freed
  - Fixed synchronization issues pointer for Sasiko for the patch that
    handles multiple WC page allocation
  - Adding a cq and srq reference to avoid UAF
  - Add a zero check ureq->sq_slots
  - Adds a rollback code when ioremap fails
  - Handles request to getting toggle mem on devices that doesn't
    support the feature


Selvin Xavier (15):
  RDMA/bnxt_re: Initialize dpi variable to zero
  RDMA/bnxt_re: Free SRQ toggle page after firmware teardown
  RDMA/bnxt_re: Free CQ toggle page after firmware teardown
  RDMA/bnxt_re: Avoid any race while handling the hash list of CQ
  RDMA/bnxt_re: Avoid any race while handling the hash list of SRQ
  RDMA/bnxt_re: Add ownership check while getting the CQ toggle page
  RDMA/bnxt_re: Add ownership check while getting the SRQ toggle page
  RDMA/bnxt_re: Avoid displaying the kernel pointer
  RDMA/bnxt_re: Add a max slot check for SQ
  RDMA/bnxt_re: Proper rollback if the ioremap fails
  RDMA/bnxt_re: Avoid repeated requests to allocate WC pages
  RDMA/bnxt_re: Fix the cleanup upon error during SRQ create
  RDMA/bnxt_re: Fix the cleanup upon error during CQ create
  RDMA/bnxt_re: Fail DBR related page allocation UAPIs if the feature is
    disabled
  RDMA/bnxt_re: Reject GET_TOGGLE_MEM when toggle page was not allocated

 drivers/infiniband/hw/bnxt_re/bnxt_re.h   |  2 +
 drivers/infiniband/hw/bnxt_re/ib_verbs.c  | 97 +++++++++++++++++++++--
 drivers/infiniband/hw/bnxt_re/ib_verbs.h  |  9 +++
 drivers/infiniband/hw/bnxt_re/main.c      |  4 +-
 drivers/infiniband/hw/bnxt_re/qplib_res.c | 11 +++
 drivers/infiniband/hw/bnxt_re/qplib_sp.h  |  1 +
 drivers/infiniband/hw/bnxt_re/uapi.c      | 61 ++++++++++++--
 7 files changed, 169 insertions(+), 16 deletions(-)

-- 
2.39.3


^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH rdma-rc v2 01/15] RDMA/bnxt_re: Initialize dpi variable to zero
  2026-06-15 22:47 [PATCH rdma-rc v2 00/15] RDMA/bnxt_re: Generic driver fixes Selvin Xavier
@ 2026-06-15 22:47 ` Selvin Xavier
  2026-06-15 22:47 ` [PATCH rdma-rc v2 02/15] RDMA/bnxt_re: Free SRQ toggle page after firmware teardown Selvin Xavier
                   ` (13 subsequent siblings)
  14 siblings, 0 replies; 16+ messages in thread
From: Selvin Xavier @ 2026-06-15 22:47 UTC (permalink / raw)
  To: leon, jgg
  Cc: linux-rdma, andrew.gospodarek, kalesh-anakkur.purayil,
	sriharsha.basavapatna, Selvin Xavier, Anantha Prabhu

dpi is initialized only for BNXT_RE_ALLOC_WC_PAGE, but copied
for all the cases. So initialize the dpi to 0.

Fixes: eee6268421a2 ("RDMA/bnxt_re: Move the UAPI methods to a dedicated file")
Fixes: 360da60d6c6e ("RDMA/bnxt_re: Enable low latency push")
Reviewed-by: Anantha Prabhu <anantha.prabhu@broadcom.com>
Signed-off-by: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
Signed-off-by: Selvin Xavier <selvin.xavier@broadcom.com>
---
 drivers/infiniband/hw/bnxt_re/uapi.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/infiniband/hw/bnxt_re/uapi.c b/drivers/infiniband/hw/bnxt_re/uapi.c
index 9e68b4a7e952..b9922360f11b 100644
--- a/drivers/infiniband/hw/bnxt_re/uapi.c
+++ b/drivers/infiniband/hw/bnxt_re/uapi.c
@@ -76,8 +76,8 @@ static int UVERBS_HANDLER(BNXT_RE_METHOD_ALLOC_PAGE)(struct uverbs_attr_bundle *
 	struct ib_ucontext *ib_uctx;
 	struct bnxt_re_dev *rdev;
 	u64 mmap_offset;
+	u32 dpi = 0;
 	u32 length;
-	u32 dpi;
 	u64 addr;
 	int err;
 
-- 
2.39.3


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH rdma-rc v2 02/15] RDMA/bnxt_re: Free SRQ toggle page after firmware teardown
  2026-06-15 22:47 [PATCH rdma-rc v2 00/15] RDMA/bnxt_re: Generic driver fixes Selvin Xavier
  2026-06-15 22:47 ` [PATCH rdma-rc v2 01/15] RDMA/bnxt_re: Initialize dpi variable to zero Selvin Xavier
@ 2026-06-15 22:47 ` Selvin Xavier
  2026-06-15 22:47 ` [PATCH rdma-rc v2 03/15] RDMA/bnxt_re: Free CQ " Selvin Xavier
                   ` (12 subsequent siblings)
  14 siblings, 0 replies; 16+ messages in thread
From: Selvin Xavier @ 2026-06-15 22:47 UTC (permalink / raw)
  To: leon, jgg
  Cc: linux-rdma, andrew.gospodarek, kalesh-anakkur.purayil,
	sriharsha.basavapatna, Selvin Xavier

Free the toggle page only after firmware teardown completes so that
an NQ interrupt arriving during bnxt_qplib_destroy_srq() won't write
the toggle values to an already-freed page. Move free_page() after
bnxt_qplib_destroy_srq().

Fixes: 181028a0d84c ("RDMA/bnxt_re: Share a page to expose per SRQ info with userspace")
Signed-off-by: Selvin Xavier <selvin.xavier@broadcom.com>
---
 drivers/infiniband/hw/bnxt_re/ib_verbs.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.c b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
index b1c489867fc7..25bfa6646f58 100644
--- a/drivers/infiniband/hw/bnxt_re/ib_verbs.c
+++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
@@ -2149,11 +2149,11 @@ int bnxt_re_destroy_srq(struct ib_srq *ib_srq, struct ib_udata *udata)
 	if (ret)
 		return ret;
 
-	if (rdev->chip_ctx->modes.toggle_bits & BNXT_QPLIB_SRQ_TOGGLE_BIT) {
-		free_page((unsigned long)srq->uctx_srq_page);
+	if (rdev->chip_ctx->modes.toggle_bits & BNXT_QPLIB_SRQ_TOGGLE_BIT)
 		hash_del(&srq->hash_entry);
-	}
 	bnxt_qplib_destroy_srq(&rdev->qplib_res, qplib_srq);
+	if (rdev->chip_ctx->modes.toggle_bits & BNXT_QPLIB_SRQ_TOGGLE_BIT)
+		free_page((unsigned long)srq->uctx_srq_page);
 	ib_umem_release(srq->umem);
 	atomic_dec(&rdev->stats.res.srq_count);
 	return ib_respond_empty_udata(udata);
-- 
2.39.3


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH rdma-rc v2 03/15] RDMA/bnxt_re: Free CQ toggle page after firmware teardown
  2026-06-15 22:47 [PATCH rdma-rc v2 00/15] RDMA/bnxt_re: Generic driver fixes Selvin Xavier
  2026-06-15 22:47 ` [PATCH rdma-rc v2 01/15] RDMA/bnxt_re: Initialize dpi variable to zero Selvin Xavier
  2026-06-15 22:47 ` [PATCH rdma-rc v2 02/15] RDMA/bnxt_re: Free SRQ toggle page after firmware teardown Selvin Xavier
@ 2026-06-15 22:47 ` Selvin Xavier
  2026-06-15 22:47 ` [PATCH rdma-rc v2 04/15] RDMA/bnxt_re: Avoid any race while handling the hash list of CQ Selvin Xavier
                   ` (11 subsequent siblings)
  14 siblings, 0 replies; 16+ messages in thread
From: Selvin Xavier @ 2026-06-15 22:47 UTC (permalink / raw)
  To: leon, jgg
  Cc: linux-rdma, andrew.gospodarek, kalesh-anakkur.purayil,
	sriharsha.basavapatna, Selvin Xavier

Free the toggle page only after firmware teardown completes so that
an NQ interrupt arriving during bnxt_qplib_destroy_cq() won't write
the toggle value to an already-freed page. Move free_page() after
bnxt_qplib_destroy_cq.

Fixes: e275919d9669 ("RDMA/bnxt_re: Share a page to expose per CQ info with userspace")
Signed-off-by: Selvin Xavier <selvin.xavier@broadcom.com>
---
 drivers/infiniband/hw/bnxt_re/ib_verbs.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.c b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
index 25bfa6646f58..05b5b5936433 100644
--- a/drivers/infiniband/hw/bnxt_re/ib_verbs.c
+++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
@@ -3452,11 +3452,11 @@ int bnxt_re_destroy_cq(struct ib_cq *ib_cq, struct ib_udata *udata)
 	if (ret)
 		return ret;
 
-	if (cctx->modes.toggle_bits & BNXT_QPLIB_CQ_TOGGLE_BIT) {
-		free_page((unsigned long)cq->uctx_cq_page);
+	if (cctx->modes.toggle_bits & BNXT_QPLIB_CQ_TOGGLE_BIT)
 		hash_del(&cq->hash_entry);
-	}
 	bnxt_qplib_destroy_cq(&rdev->qplib_res, &cq->qplib_cq);
+	if (cctx->modes.toggle_bits & BNXT_QPLIB_CQ_TOGGLE_BIT)
+		free_page((unsigned long)cq->uctx_cq_page);
 
 	bnxt_re_put_nq(rdev, nq);
 
-- 
2.39.3


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH rdma-rc v2 04/15] RDMA/bnxt_re: Avoid any race while handling the hash list of CQ
  2026-06-15 22:47 [PATCH rdma-rc v2 00/15] RDMA/bnxt_re: Generic driver fixes Selvin Xavier
                   ` (2 preceding siblings ...)
  2026-06-15 22:47 ` [PATCH rdma-rc v2 03/15] RDMA/bnxt_re: Free CQ " Selvin Xavier
@ 2026-06-15 22:47 ` Selvin Xavier
  2026-06-15 22:47 ` [PATCH rdma-rc v2 05/15] RDMA/bnxt_re: Avoid any race while handling the hash list of SRQ Selvin Xavier
                   ` (10 subsequent siblings)
  14 siblings, 0 replies; 16+ messages in thread
From: Selvin Xavier @ 2026-06-15 22:47 UTC (permalink / raw)
  To: leon, jgg
  Cc: linux-rdma, andrew.gospodarek, kalesh-anakkur.purayil,
	sriharsha.basavapatna, Selvin Xavier

Add/Delete to/from hash list needs to be synchronized with the traversing
of the hash list. Add a mutex for this synchronization. Also add a
reference for the CQ to avoid any usage of the CQ structures after the
CQ is freed.

Fixes: e275919d9669 ("RDMA/bnxt_re: Share a page to expose per CQ info with userspace")
Reviewed-by: Sriharsha Basavapatna <sriharsha.basavapatna@broadcom.com>
Signed-off-by: Selvin Xavier <selvin.xavier@broadcom.com>
---
 drivers/infiniband/hw/bnxt_re/bnxt_re.h  |  1 +
 drivers/infiniband/hw/bnxt_re/ib_verbs.c | 28 ++++++++++++++++++++++--
 drivers/infiniband/hw/bnxt_re/ib_verbs.h |  3 +++
 drivers/infiniband/hw/bnxt_re/main.c     |  1 +
 drivers/infiniband/hw/bnxt_re/uapi.c     |  4 ++++
 5 files changed, 35 insertions(+), 2 deletions(-)

diff --git a/drivers/infiniband/hw/bnxt_re/bnxt_re.h b/drivers/infiniband/hw/bnxt_re/bnxt_re.h
index 3a7ce4729fcf..c346dec14dec 100644
--- a/drivers/infiniband/hw/bnxt_re/bnxt_re.h
+++ b/drivers/infiniband/hw/bnxt_re/bnxt_re.h
@@ -217,6 +217,7 @@ struct bnxt_re_dev {
 	struct delayed_work dbq_pacing_work;
 	DECLARE_HASHTABLE(cq_hash, MAX_CQ_HASH_BITS);
 	DECLARE_HASHTABLE(srq_hash, MAX_SRQ_HASH_BITS);
+	struct mutex			cq_hash_lock;  /* guards cq_hash  */
 	struct dentry			*dbg_root;
 	struct dentry			*qp_debugfs;
 	unsigned long			event_bitmap;
diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.c b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
index 05b5b5936433..e74f19c5038a 100644
--- a/drivers/infiniband/hw/bnxt_re/ib_verbs.c
+++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
@@ -3435,6 +3435,18 @@ static void bnxt_re_put_nq(struct bnxt_re_dev *rdev, struct bnxt_qplib_nq *nq)
 }
 
 /* Completion Queues */
+static void bnxt_re_cq_release(struct kref *ref)
+{
+	struct bnxt_re_cq *cq = container_of(ref, struct bnxt_re_cq, cq_ref);
+
+	complete(&cq->cq_destroy_comp);
+}
+
+void bnxt_re_put_cq(struct bnxt_re_cq *cq)
+{
+	kref_put(&cq->cq_ref, bnxt_re_cq_release);
+}
+
 int bnxt_re_destroy_cq(struct ib_cq *ib_cq, struct ib_udata *udata)
 {
 	struct bnxt_qplib_chip_ctx *cctx;
@@ -3452,10 +3464,18 @@ int bnxt_re_destroy_cq(struct ib_cq *ib_cq, struct ib_udata *udata)
 	if (ret)
 		return ret;
 
-	if (cctx->modes.toggle_bits & BNXT_QPLIB_CQ_TOGGLE_BIT)
+	if (cctx->modes.toggle_bits & BNXT_QPLIB_CQ_TOGGLE_BIT && cq->uctx) {
+		mutex_lock(&rdev->cq_hash_lock);
 		hash_del(&cq->hash_entry);
+		mutex_unlock(&rdev->cq_hash_lock);
+		/* Drop the creator's reference and wait for any concurrent
+		 * bnxt_re_search_for_cq() caller to finish with the pointer.
+		 */
+		kref_put(&cq->cq_ref, bnxt_re_cq_release);
+		wait_for_completion(&cq->cq_destroy_comp);
+	}
 	bnxt_qplib_destroy_cq(&rdev->qplib_res, &cq->qplib_cq);
-	if (cctx->modes.toggle_bits & BNXT_QPLIB_CQ_TOGGLE_BIT)
+	if (cctx->modes.toggle_bits & BNXT_QPLIB_CQ_TOGGLE_BIT && cq->uctx)
 		free_page((unsigned long)cq->uctx_cq_page);
 
 	bnxt_re_put_nq(rdev, nq);
@@ -3531,7 +3551,11 @@ int bnxt_re_create_user_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *att
 	spin_lock_init(&cq->cq_lock);
 
 	if (cctx->modes.toggle_bits & BNXT_QPLIB_CQ_TOGGLE_BIT) {
+		kref_init(&cq->cq_ref);
+		init_completion(&cq->cq_destroy_comp);
+		mutex_lock(&rdev->cq_hash_lock);
 		hash_add(rdev->cq_hash, &cq->hash_entry, cq->qplib_cq.id);
+		mutex_unlock(&rdev->cq_hash_lock);
 		/* Allocate a page */
 		cq->uctx_cq_page = (void *)get_zeroed_page(GFP_KERNEL);
 		if (!cq->uctx_cq_page) {
diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.h b/drivers/infiniband/hw/bnxt_re/ib_verbs.h
index 4d6d1259a795..aaec5dbc322e 100644
--- a/drivers/infiniband/hw/bnxt_re/ib_verbs.h
+++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.h
@@ -114,6 +114,8 @@ struct bnxt_re_cq {
 	int			resize_cqe;
 	void			*uctx_cq_page;
 	struct hlist_node	hash_entry;
+	struct kref		cq_ref;
+	struct completion	cq_destroy_comp;
 };
 
 struct bnxt_re_mr {
@@ -265,6 +267,7 @@ int bnxt_re_create_user_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *att
 int bnxt_re_resize_cq(struct ib_cq *ibcq, unsigned int cqe,
 		      struct ib_udata *udata);
 int bnxt_re_destroy_cq(struct ib_cq *cq, struct ib_udata *udata);
+void bnxt_re_put_cq(struct bnxt_re_cq *cq);
 int bnxt_re_poll_cq(struct ib_cq *cq, int num_entries, struct ib_wc *wc);
 int bnxt_re_req_notify_cq(struct ib_cq *cq, enum ib_cq_notify_flags flags);
 struct ib_mr *bnxt_re_get_dma_mr(struct ib_pd *pd, int mr_access_flags);
diff --git a/drivers/infiniband/hw/bnxt_re/main.c b/drivers/infiniband/hw/bnxt_re/main.c
index a892f1172917..902eda6011ad 100644
--- a/drivers/infiniband/hw/bnxt_re/main.c
+++ b/drivers/infiniband/hw/bnxt_re/main.c
@@ -2340,6 +2340,7 @@ static int bnxt_re_dev_init(struct bnxt_re_dev *rdev, u8 op_type)
 			bnxt_re_vf_res_config(rdev);
 	}
 	hash_init(rdev->cq_hash);
+	mutex_init(&rdev->cq_hash_lock);
 	if (rdev->chip_ctx->modes.toggle_bits & BNXT_QPLIB_SRQ_TOGGLE_BIT)
 		hash_init(rdev->srq_hash);
 
diff --git a/drivers/infiniband/hw/bnxt_re/uapi.c b/drivers/infiniband/hw/bnxt_re/uapi.c
index b9922360f11b..a0cd2dce6168 100644
--- a/drivers/infiniband/hw/bnxt_re/uapi.c
+++ b/drivers/infiniband/hw/bnxt_re/uapi.c
@@ -26,12 +26,15 @@ static struct bnxt_re_cq *bnxt_re_search_for_cq(struct bnxt_re_dev *rdev, u32 cq
 {
 	struct bnxt_re_cq *cq = NULL, *tmp_cq;
 
+	mutex_lock(&rdev->cq_hash_lock);
 	hash_for_each_possible(rdev->cq_hash, tmp_cq, hash_entry, cq_id) {
 		if (tmp_cq->qplib_cq.id == cq_id) {
+			kref_get(&tmp_cq->cq_ref);
 			cq = tmp_cq;
 			break;
 		}
 	}
+	mutex_unlock(&rdev->cq_hash_lock);
 	return cq;
 }
 
@@ -252,6 +255,7 @@ static int UVERBS_HANDLER(BNXT_RE_METHOD_GET_TOGGLE_MEM)(struct uverbs_attr_bund
 			return -EINVAL;
 
 		addr = (u64)cq->uctx_cq_page;
+		bnxt_re_put_cq(cq);
 		break;
 	case BNXT_RE_SRQ_TOGGLE_MEM:
 		srq = bnxt_re_search_for_srq(rdev, res_id);
-- 
2.39.3


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH rdma-rc v2 05/15] RDMA/bnxt_re: Avoid any race while handling the hash list of SRQ
  2026-06-15 22:47 [PATCH rdma-rc v2 00/15] RDMA/bnxt_re: Generic driver fixes Selvin Xavier
                   ` (3 preceding siblings ...)
  2026-06-15 22:47 ` [PATCH rdma-rc v2 04/15] RDMA/bnxt_re: Avoid any race while handling the hash list of CQ Selvin Xavier
@ 2026-06-15 22:47 ` Selvin Xavier
  2026-06-15 22:47 ` [PATCH rdma-rc v2 06/15] RDMA/bnxt_re: Add ownership check while getting the CQ toggle page Selvin Xavier
                   ` (9 subsequent siblings)
  14 siblings, 0 replies; 16+ messages in thread
From: Selvin Xavier @ 2026-06-15 22:47 UTC (permalink / raw)
  To: leon, jgg
  Cc: linux-rdma, andrew.gospodarek, kalesh-anakkur.purayil,
	sriharsha.basavapatna, Selvin Xavier

Add/Delete to/from hash list needs to be synchronized with the traversing
of the hash list. Add a mutex for this synchronization to avoid any usage
of the SRQ structures after the SRQ is freed.

Fixes: 181028a0d84c ("RDMA/bnxt_re: Share a page to expose per SRQ info with userspace")
Reviewed-by: Sriharsha Basavapatna <sriharsha.basavapatna@broadcom.com>
Signed-off-by: Selvin Xavier <selvin.xavier@broadcom.com>
---
 drivers/infiniband/hw/bnxt_re/bnxt_re.h  |  1 +
 drivers/infiniband/hw/bnxt_re/ib_verbs.c | 29 ++++++++++++++++++++++--
 drivers/infiniband/hw/bnxt_re/ib_verbs.h |  3 +++
 drivers/infiniband/hw/bnxt_re/main.c     |  1 +
 drivers/infiniband/hw/bnxt_re/uapi.c     |  4 ++++
 5 files changed, 36 insertions(+), 2 deletions(-)

diff --git a/drivers/infiniband/hw/bnxt_re/bnxt_re.h b/drivers/infiniband/hw/bnxt_re/bnxt_re.h
index c346dec14dec..5fec474fcc2e 100644
--- a/drivers/infiniband/hw/bnxt_re/bnxt_re.h
+++ b/drivers/infiniband/hw/bnxt_re/bnxt_re.h
@@ -218,6 +218,7 @@ struct bnxt_re_dev {
 	DECLARE_HASHTABLE(cq_hash, MAX_CQ_HASH_BITS);
 	DECLARE_HASHTABLE(srq_hash, MAX_SRQ_HASH_BITS);
 	struct mutex			cq_hash_lock;  /* guards cq_hash  */
+	struct mutex			srq_hash_lock; /* guards srq_hash */
 	struct dentry			*dbg_root;
 	struct dentry			*qp_debugfs;
 	unsigned long			event_bitmap;
diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.c b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
index e74f19c5038a..43a2aedc4819 100644
--- a/drivers/infiniband/hw/bnxt_re/ib_verbs.c
+++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
@@ -2137,6 +2137,19 @@ static enum ib_mtu __to_ib_mtu(u32 mtu)
 }
 
 /* Shared Receive Queues */
+/* Shared Receive Queue lifetime helpers */
+static void bnxt_re_srq_release(struct kref *ref)
+{
+	struct bnxt_re_srq *srq = container_of(ref, struct bnxt_re_srq, srq_ref);
+
+	complete(&srq->srq_destroy_comp);
+}
+
+void bnxt_re_put_srq(struct bnxt_re_srq *srq)
+{
+	kref_put(&srq->srq_ref, bnxt_re_srq_release);
+}
+
 int bnxt_re_destroy_srq(struct ib_srq *ib_srq, struct ib_udata *udata)
 {
 	struct bnxt_re_srq *srq = container_of(ib_srq, struct bnxt_re_srq,
@@ -2149,10 +2162,18 @@ int bnxt_re_destroy_srq(struct ib_srq *ib_srq, struct ib_udata *udata)
 	if (ret)
 		return ret;
 
-	if (rdev->chip_ctx->modes.toggle_bits & BNXT_QPLIB_SRQ_TOGGLE_BIT)
+	if (rdev->chip_ctx->modes.toggle_bits & BNXT_QPLIB_SRQ_TOGGLE_BIT && srq->uctx) {
+		mutex_lock(&rdev->srq_hash_lock);
 		hash_del(&srq->hash_entry);
+		mutex_unlock(&rdev->srq_hash_lock);
+		/* Drop the creator's reference and wait for any concurrent
+		 * bnxt_re_search_for_srq() caller to finish with the pointer.
+		 */
+		kref_put(&srq->srq_ref, bnxt_re_srq_release);
+		wait_for_completion(&srq->srq_destroy_comp);
+	}
 	bnxt_qplib_destroy_srq(&rdev->qplib_res, qplib_srq);
-	if (rdev->chip_ctx->modes.toggle_bits & BNXT_QPLIB_SRQ_TOGGLE_BIT)
+	if (rdev->chip_ctx->modes.toggle_bits & BNXT_QPLIB_SRQ_TOGGLE_BIT && srq->uctx)
 		free_page((unsigned long)srq->uctx_srq_page);
 	ib_umem_release(srq->umem);
 	atomic_dec(&rdev->stats.res.srq_count);
@@ -2260,7 +2281,11 @@ int bnxt_re_create_srq(struct ib_srq *ib_srq,
 
 		resp.srqid = srq->qplib_srq.id;
 		if (rdev->chip_ctx->modes.toggle_bits & BNXT_QPLIB_SRQ_TOGGLE_BIT) {
+			kref_init(&srq->srq_ref);
+			init_completion(&srq->srq_destroy_comp);
+			mutex_lock(&rdev->srq_hash_lock);
 			hash_add(rdev->srq_hash, &srq->hash_entry, srq->qplib_srq.id);
+			mutex_unlock(&rdev->srq_hash_lock);
 			srq->uctx_srq_page = (void *)get_zeroed_page(GFP_KERNEL);
 			if (!srq->uctx_srq_page) {
 				rc = -ENOMEM;
diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.h b/drivers/infiniband/hw/bnxt_re/ib_verbs.h
index aaec5dbc322e..1456fdc3935b 100644
--- a/drivers/infiniband/hw/bnxt_re/ib_verbs.h
+++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.h
@@ -79,6 +79,8 @@ struct bnxt_re_srq {
 	spinlock_t		lock;		/* protect srq */
 	void			*uctx_srq_page;
 	struct hlist_node       hash_entry;
+	struct kref		srq_ref;
+	struct completion	srq_destroy_comp;
 };
 
 struct bnxt_re_qp {
@@ -247,6 +249,7 @@ int bnxt_re_modify_srq(struct ib_srq *srq, struct ib_srq_attr *srq_attr,
 		       struct ib_udata *udata);
 int bnxt_re_query_srq(struct ib_srq *srq, struct ib_srq_attr *srq_attr);
 int bnxt_re_destroy_srq(struct ib_srq *srq, struct ib_udata *udata);
+void bnxt_re_put_srq(struct bnxt_re_srq *srq);
 int bnxt_re_post_srq_recv(struct ib_srq *srq, const struct ib_recv_wr *recv_wr,
 			  const struct ib_recv_wr **bad_recv_wr);
 int bnxt_re_create_qp(struct ib_qp *qp, struct ib_qp_init_attr *qp_init_attr,
diff --git a/drivers/infiniband/hw/bnxt_re/main.c b/drivers/infiniband/hw/bnxt_re/main.c
index 902eda6011ad..8e89218bd666 100644
--- a/drivers/infiniband/hw/bnxt_re/main.c
+++ b/drivers/infiniband/hw/bnxt_re/main.c
@@ -2343,6 +2343,7 @@ static int bnxt_re_dev_init(struct bnxt_re_dev *rdev, u8 op_type)
 	mutex_init(&rdev->cq_hash_lock);
 	if (rdev->chip_ctx->modes.toggle_bits & BNXT_QPLIB_SRQ_TOGGLE_BIT)
 		hash_init(rdev->srq_hash);
+	mutex_init(&rdev->srq_hash_lock);
 
 	bnxt_re_debugfs_add_pdev(rdev);
 
diff --git a/drivers/infiniband/hw/bnxt_re/uapi.c b/drivers/infiniband/hw/bnxt_re/uapi.c
index a0cd2dce6168..1d7031a23b02 100644
--- a/drivers/infiniband/hw/bnxt_re/uapi.c
+++ b/drivers/infiniband/hw/bnxt_re/uapi.c
@@ -42,12 +42,15 @@ static struct bnxt_re_srq *bnxt_re_search_for_srq(struct bnxt_re_dev *rdev, u32
 {
 	struct bnxt_re_srq *srq = NULL, *tmp_srq;
 
+	mutex_lock(&rdev->srq_hash_lock);
 	hash_for_each_possible(rdev->srq_hash, tmp_srq, hash_entry, srq_id) {
 		if (tmp_srq->qplib_srq.id == srq_id) {
+			kref_get(&tmp_srq->srq_ref);
 			srq = tmp_srq;
 			break;
 		}
 	}
+	mutex_unlock(&rdev->srq_hash_lock);
 	return srq;
 }
 
@@ -263,6 +266,7 @@ static int UVERBS_HANDLER(BNXT_RE_METHOD_GET_TOGGLE_MEM)(struct uverbs_attr_bund
 			return -EINVAL;
 
 		addr = (u64)srq->uctx_srq_page;
+		bnxt_re_put_srq(srq);
 		break;
 
 	default:
-- 
2.39.3


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH rdma-rc v2 06/15] RDMA/bnxt_re: Add ownership check while getting the CQ toggle page
  2026-06-15 22:47 [PATCH rdma-rc v2 00/15] RDMA/bnxt_re: Generic driver fixes Selvin Xavier
                   ` (4 preceding siblings ...)
  2026-06-15 22:47 ` [PATCH rdma-rc v2 05/15] RDMA/bnxt_re: Avoid any race while handling the hash list of SRQ Selvin Xavier
@ 2026-06-15 22:47 ` Selvin Xavier
  2026-06-15 22:47 ` [PATCH rdma-rc v2 07/15] RDMA/bnxt_re: Add ownership check while getting the SRQ " Selvin Xavier
                   ` (8 subsequent siblings)
  14 siblings, 0 replies; 16+ messages in thread
From: Selvin Xavier @ 2026-06-15 22:47 UTC (permalink / raw)
  To: leon, jgg
  Cc: linux-rdma, andrew.gospodarek, kalesh-anakkur.purayil,
	sriharsha.basavapatna, Selvin Xavier

The cq resource id provided by user-space is used for
searching the driver CQ structure. Validate if the context
currently issuing the request is same as the context
created the resource.

Fixes: eee6268421a2 ("RDMA/bnxt_re: Move the UAPI methods to a dedicated file")
Fixes: e275919d9669 ("RDMA/bnxt_re: Share a page to expose per CQ info with userspace")
Reviewed-by: Sriharsha Basavapatna <sriharsha.basavapatna@broadcom.com>
Signed-off-by: Selvin Xavier <selvin.xavier@broadcom.com>
---
 drivers/infiniband/hw/bnxt_re/ib_verbs.c | 1 +
 drivers/infiniband/hw/bnxt_re/ib_verbs.h | 1 +
 drivers/infiniband/hw/bnxt_re/uapi.c     | 5 +++++
 3 files changed, 7 insertions(+)

diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.c b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
index 43a2aedc4819..13b18e4ae7cd 100644
--- a/drivers/infiniband/hw/bnxt_re/ib_verbs.c
+++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
@@ -3534,6 +3534,7 @@ int bnxt_re_create_user_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *att
 		return -EINVAL;
 
 	cq->rdev = rdev;
+	cq->uctx = &uctx->ib_uctx;
 	cctx = rdev->chip_ctx;
 	cq->qplib_cq.cq_handle = (u64)(unsigned long)(&cq->qplib_cq);
 
diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.h b/drivers/infiniband/hw/bnxt_re/ib_verbs.h
index 1456fdc3935b..7217b4692419 100644
--- a/drivers/infiniband/hw/bnxt_re/ib_verbs.h
+++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.h
@@ -104,6 +104,7 @@ struct bnxt_re_qp {
 struct bnxt_re_cq {
 	struct ib_cq		ib_cq;
 	struct bnxt_re_dev	*rdev;
+	struct ib_ucontext	*uctx;
 	spinlock_t              cq_lock;	/* protect cq */
 	u16			cq_count;
 	u16			cq_period;
diff --git a/drivers/infiniband/hw/bnxt_re/uapi.c b/drivers/infiniband/hw/bnxt_re/uapi.c
index 1d7031a23b02..3f5ae1920aef 100644
--- a/drivers/infiniband/hw/bnxt_re/uapi.c
+++ b/drivers/infiniband/hw/bnxt_re/uapi.c
@@ -257,6 +257,11 @@ static int UVERBS_HANDLER(BNXT_RE_METHOD_GET_TOGGLE_MEM)(struct uverbs_attr_bund
 		if (!cq)
 			return -EINVAL;
 
+		if (cq->uctx != ib_uctx) {
+			bnxt_re_put_cq(cq);
+			return -EINVAL;
+		}
+
 		addr = (u64)cq->uctx_cq_page;
 		bnxt_re_put_cq(cq);
 		break;
-- 
2.39.3


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH rdma-rc v2 07/15] RDMA/bnxt_re: Add ownership check while getting the SRQ toggle page
  2026-06-15 22:47 [PATCH rdma-rc v2 00/15] RDMA/bnxt_re: Generic driver fixes Selvin Xavier
                   ` (5 preceding siblings ...)
  2026-06-15 22:47 ` [PATCH rdma-rc v2 06/15] RDMA/bnxt_re: Add ownership check while getting the CQ toggle page Selvin Xavier
@ 2026-06-15 22:47 ` Selvin Xavier
  2026-06-15 22:47 ` [PATCH rdma-rc v2 08/15] RDMA/bnxt_re: Avoid displaying the kernel pointer Selvin Xavier
                   ` (7 subsequent siblings)
  14 siblings, 0 replies; 16+ messages in thread
From: Selvin Xavier @ 2026-06-15 22:47 UTC (permalink / raw)
  To: leon, jgg
  Cc: linux-rdma, andrew.gospodarek, kalesh-anakkur.purayil,
	sriharsha.basavapatna, Selvin Xavier

The SRQ resource id provided by user-space is used for
searching the driver SRQ structure. Validate if the context
currently issuing the request is same as the context
created the resource.

Fixes: eee6268421a2 ("RDMA/bnxt_re: Move the UAPI methods to a dedicated file")
Fixes: 181028a0d84c ("RDMA/bnxt_re: Share a page to expose per SRQ info with userspace")
Reviewed-by: Sriharsha Basavapatna <sriharsha.basavapatna@broadcom.com>
Signed-off-by: Selvin Xavier <selvin.xavier@broadcom.com>
---
 drivers/infiniband/hw/bnxt_re/ib_verbs.c | 1 +
 drivers/infiniband/hw/bnxt_re/ib_verbs.h | 1 +
 drivers/infiniband/hw/bnxt_re/uapi.c     | 5 +++++
 3 files changed, 7 insertions(+)

diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.c b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
index 13b18e4ae7cd..e7a08b12ca21 100644
--- a/drivers/infiniband/hw/bnxt_re/ib_verbs.c
+++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
@@ -2246,6 +2246,7 @@ int bnxt_re_create_srq(struct ib_srq *ib_srq,
 
 	uctx = rdma_udata_to_drv_context(udata, struct bnxt_re_ucontext, ib_uctx);
 	srq->rdev = rdev;
+	srq->uctx = uctx ? &uctx->ib_uctx : NULL;
 	srq->qplib_srq.pd = &pd->qplib_pd;
 	srq->qplib_srq.dpi = &rdev->dpi_privileged;
 	/* Allocate 1 more than what's provided so posting max doesn't
diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.h b/drivers/infiniband/hw/bnxt_re/ib_verbs.h
index 7217b4692419..ff3148340fd3 100644
--- a/drivers/infiniband/hw/bnxt_re/ib_verbs.h
+++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.h
@@ -73,6 +73,7 @@ struct bnxt_re_ah {
 struct bnxt_re_srq {
 	struct ib_srq		ib_srq;
 	struct bnxt_re_dev	*rdev;
+	struct ib_ucontext	*uctx;
 	u32			srq_limit;
 	struct bnxt_qplib_srq	qplib_srq;
 	struct ib_umem		*umem;
diff --git a/drivers/infiniband/hw/bnxt_re/uapi.c b/drivers/infiniband/hw/bnxt_re/uapi.c
index 3f5ae1920aef..ae8f46ab6961 100644
--- a/drivers/infiniband/hw/bnxt_re/uapi.c
+++ b/drivers/infiniband/hw/bnxt_re/uapi.c
@@ -270,6 +270,11 @@ static int UVERBS_HANDLER(BNXT_RE_METHOD_GET_TOGGLE_MEM)(struct uverbs_attr_bund
 		if (!srq)
 			return -EINVAL;
 
+		if (srq->uctx != ib_uctx) {
+			bnxt_re_put_srq(srq);
+			return -EINVAL;
+		}
+
 		addr = (u64)srq->uctx_srq_page;
 		bnxt_re_put_srq(srq);
 		break;
-- 
2.39.3


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH rdma-rc v2 08/15] RDMA/bnxt_re: Avoid displaying the kernel pointer
  2026-06-15 22:47 [PATCH rdma-rc v2 00/15] RDMA/bnxt_re: Generic driver fixes Selvin Xavier
                   ` (6 preceding siblings ...)
  2026-06-15 22:47 ` [PATCH rdma-rc v2 07/15] RDMA/bnxt_re: Add ownership check while getting the SRQ " Selvin Xavier
@ 2026-06-15 22:47 ` Selvin Xavier
  2026-06-15 22:47 ` [PATCH rdma-rc v2 09/15] RDMA/bnxt_re: Add a max slot check for SQ Selvin Xavier
                   ` (6 subsequent siblings)
  14 siblings, 0 replies; 16+ messages in thread
From: Selvin Xavier @ 2026-06-15 22:47 UTC (permalink / raw)
  To: leon, jgg
  Cc: linux-rdma, andrew.gospodarek, kalesh-anakkur.purayil,
	sriharsha.basavapatna, Selvin Xavier

While dumping the info on MR using the rdma tool, we
dump the mr_hwq which is a kernel pointer. There is
no need to expose this value for end user. So avoid
it.

Fixes: 7363eb76b7f3 ("RDMA/bnxt_re: Support driver specific data collection using rdma tool")
Reviewed-by: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
Signed-off-by: Selvin Xavier <selvin.xavier@broadcom.com>
---
 drivers/infiniband/hw/bnxt_re/main.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/infiniband/hw/bnxt_re/main.c b/drivers/infiniband/hw/bnxt_re/main.c
index 8e89218bd666..6915fc3f1392 100644
--- a/drivers/infiniband/hw/bnxt_re/main.c
+++ b/drivers/infiniband/hw/bnxt_re/main.c
@@ -1093,8 +1093,6 @@ static int bnxt_re_fill_res_mr_entry(struct sk_buff *msg, struct ib_mr *ib_mr)
 		goto err;
 	if (rdma_nl_put_driver_u32(msg, "element_size", mr_hwq->element_size))
 		goto err;
-	if (rdma_nl_put_driver_u64_hex(msg, "hwq", (unsigned long)mr_hwq))
-		goto err;
 	if (rdma_nl_put_driver_u64_hex(msg, "va", mr->qplib_mr.va))
 		goto err;
 
-- 
2.39.3


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH rdma-rc v2 09/15] RDMA/bnxt_re: Add a max slot check for SQ
  2026-06-15 22:47 [PATCH rdma-rc v2 00/15] RDMA/bnxt_re: Generic driver fixes Selvin Xavier
                   ` (7 preceding siblings ...)
  2026-06-15 22:47 ` [PATCH rdma-rc v2 08/15] RDMA/bnxt_re: Avoid displaying the kernel pointer Selvin Xavier
@ 2026-06-15 22:47 ` Selvin Xavier
  2026-06-15 22:47 ` [PATCH rdma-rc v2 10/15] RDMA/bnxt_re: Proper rollback if the ioremap fails Selvin Xavier
                   ` (5 subsequent siblings)
  14 siblings, 0 replies; 16+ messages in thread
From: Selvin Xavier @ 2026-06-15 22:47 UTC (permalink / raw)
  To: leon, jgg
  Cc: linux-rdma, andrew.gospodarek, kalesh-anakkur.purayil,
	sriharsha.basavapatna, Selvin Xavier

The variable WQE mode must be validated against
the maximum slots supported by HW. The max supported
value is 64K. Adding a max and min check and fail if user
supplied value is more than the max supported and zero.

Fixes: d8ea645d6984 ("RDMA/bnxt_re: Handle variable WQE support for user applications")
Reviewed-by: Sriharsha Basavapatna <sriharsha.basavapatna@broadcom.com>
Signed-off-by: Selvin Xavier <selvin.xavier@broadcom.com>
---
 drivers/infiniband/hw/bnxt_re/ib_verbs.c | 3 +++
 drivers/infiniband/hw/bnxt_re/qplib_sp.h | 1 +
 2 files changed, 4 insertions(+)

diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.c b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
index e7a08b12ca21..1626bbdd0d68 100644
--- a/drivers/infiniband/hw/bnxt_re/ib_verbs.c
+++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
@@ -1748,6 +1748,9 @@ static int bnxt_re_init_qp_attr(struct bnxt_re_qp *qp, struct bnxt_re_pd *pd,
 		return qptype;
 	qplqp->type = (u8)qptype;
 	qplqp->wqe_mode = bnxt_re_is_var_size_supported(rdev, uctx);
+	if (uctx && qplqp->wqe_mode == BNXT_QPLIB_WQE_MODE_VARIABLE &&
+	    (!ureq->sq_slots || ureq->sq_slots > BNXT_RE_MAX_SQ_SLOTS))
+		return -EINVAL;
 	if (fixed_que_attr) {
 		if (qplqp->wqe_mode != BNXT_QPLIB_WQE_MODE_VARIABLE)
 			return -EOPNOTSUPP;
diff --git a/drivers/infiniband/hw/bnxt_re/qplib_sp.h b/drivers/infiniband/hw/bnxt_re/qplib_sp.h
index 9fadd637cb5b..c4193ae75b54 100644
--- a/drivers/infiniband/hw/bnxt_re/qplib_sp.h
+++ b/drivers/infiniband/hw/bnxt_re/qplib_sp.h
@@ -369,6 +369,7 @@ int bnxt_qplib_destroy_flow(struct bnxt_qplib_res *res);
 #define BNXT_VAR_MAX_SLOT_ALIGN 256
 #define BNXT_VAR_MAX_SGE        13
 #define BNXT_RE_MAX_RQ_WQES     65536
+#define BNXT_RE_MAX_SQ_SLOTS    65536
 
 #define BNXT_STATIC_MAX_SGE	6
 
-- 
2.39.3


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH rdma-rc v2 10/15] RDMA/bnxt_re: Proper rollback if the ioremap fails
  2026-06-15 22:47 [PATCH rdma-rc v2 00/15] RDMA/bnxt_re: Generic driver fixes Selvin Xavier
                   ` (8 preceding siblings ...)
  2026-06-15 22:47 ` [PATCH rdma-rc v2 09/15] RDMA/bnxt_re: Add a max slot check for SQ Selvin Xavier
@ 2026-06-15 22:47 ` Selvin Xavier
  2026-06-15 22:47 ` [PATCH rdma-rc v2 11/15] RDMA/bnxt_re: Avoid repeated requests to allocate WC pages Selvin Xavier
                   ` (4 subsequent siblings)
  14 siblings, 0 replies; 16+ messages in thread
From: Selvin Xavier @ 2026-06-15 22:47 UTC (permalink / raw)
  To: leon, jgg
  Cc: linux-rdma, andrew.gospodarek, kalesh-anakkur.purayil,
	sriharsha.basavapatna, Selvin Xavier

bnxt_qplib_alloc_dpi returns success even if ioremap fails.
Add the proper rollback when the ioremap fails and return
-ENOMEM status.

Fixes: 0ac20faf5d83 ("RDMA/bnxt_re: Reorg the bar mapping")
Fixes: 360da60d6c6e ("RDMA/bnxt_re: Enable low latency push")
Reviewed-by: Sriharsha Basavapatna <sriharsha.basavapatna@broadcom.com>
Signed-off-by: Selvin Xavier <selvin.xavier@broadcom.com>
---
 drivers/infiniband/hw/bnxt_re/qplib_res.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/drivers/infiniband/hw/bnxt_re/qplib_res.c b/drivers/infiniband/hw/bnxt_re/qplib_res.c
index 95e0489c53c3..756f8b5f042a 100644
--- a/drivers/infiniband/hw/bnxt_re/qplib_res.c
+++ b/drivers/infiniband/hw/bnxt_re/qplib_res.c
@@ -764,9 +764,13 @@ int bnxt_qplib_alloc_dpi(struct bnxt_qplib_res *res,
 		break;
 	case BNXT_QPLIB_DPI_TYPE_WC:
 		dpi->dbr = ioremap_wc(umaddr, PAGE_SIZE);
+		if (!dpi->dbr)
+			goto fail_ioremap;
 		break;
 	default:
 		dpi->dbr = ioremap(umaddr, PAGE_SIZE);
+		if (!dpi->dbr)
+			goto fail_ioremap;
 		break;
 	}
 
@@ -774,6 +778,13 @@ int bnxt_qplib_alloc_dpi(struct bnxt_qplib_res *res,
 	mutex_unlock(&res->dpi_tbl_lock);
 	return 0;
 
+fail_ioremap:
+	/* Roll back the bit we just claimed. */
+	set_bit(bit_num, dpit->tbl);
+	dpit->app_tbl[bit_num] = NULL;
+	mutex_unlock(&res->dpi_tbl_lock);
+	return -ENOMEM;
+
 }
 
 int bnxt_qplib_dealloc_dpi(struct bnxt_qplib_res *res,
-- 
2.39.3


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH rdma-rc v2 11/15] RDMA/bnxt_re: Avoid repeated requests to allocate WC pages
  2026-06-15 22:47 [PATCH rdma-rc v2 00/15] RDMA/bnxt_re: Generic driver fixes Selvin Xavier
                   ` (9 preceding siblings ...)
  2026-06-15 22:47 ` [PATCH rdma-rc v2 10/15] RDMA/bnxt_re: Proper rollback if the ioremap fails Selvin Xavier
@ 2026-06-15 22:47 ` Selvin Xavier
  2026-06-15 22:47 ` [PATCH rdma-rc v2 12/15] RDMA/bnxt_re: Fix the cleanup upon error during SRQ create Selvin Xavier
                   ` (3 subsequent siblings)
  14 siblings, 0 replies; 16+ messages in thread
From: Selvin Xavier @ 2026-06-15 22:47 UTC (permalink / raw)
  To: leon, jgg
  Cc: linux-rdma, andrew.gospodarek, kalesh-anakkur.purayil,
	sriharsha.basavapatna, Selvin Xavier

Applications can request multiple WC pages for the same ucontext.
As of now, only 1 WC page per ucontext is supported. Add a lock to
avoid concurrent access and a check to fail repeated requests.
Also, if the mmap entry insert fails for the WC, free the Doorbell
page index mapped for the WC page.

Fixes: eee6268421a2 ("RDMA/bnxt_re: Move the UAPI methods to a dedicated file")
Fixes: 360da60d6c6e ("RDMA/bnxt_re: Enable low latency push")
Reviewed-by: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
Signed-off-by: Selvin Xavier <selvin.xavier@broadcom.com>
---
 drivers/infiniband/hw/bnxt_re/ib_verbs.c |  1 +
 drivers/infiniband/hw/bnxt_re/ib_verbs.h |  1 +
 drivers/infiniband/hw/bnxt_re/uapi.c     | 33 +++++++++++++++++++-----
 3 files changed, 29 insertions(+), 6 deletions(-)

diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.c b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
index 1626bbdd0d68..dc546308b46e 100644
--- a/drivers/infiniband/hw/bnxt_re/ib_verbs.c
+++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
@@ -4801,6 +4801,7 @@ int bnxt_re_alloc_ucontext(struct ib_ucontext *ctx, struct ib_udata *udata)
 		goto fail;
 	}
 	spin_lock_init(&uctx->sh_lock);
+	mutex_init(&uctx->wcdpi_lock);
 
 	resp.comp_mask = BNXT_RE_UCNTX_CMASK_HAVE_CCTX;
 	chip_met_rev_num = rdev->chip_ctx->chip_num;
diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.h b/drivers/infiniband/hw/bnxt_re/ib_verbs.h
index ff3148340fd3..882cc17711db 100644
--- a/drivers/infiniband/hw/bnxt_re/ib_verbs.h
+++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.h
@@ -149,6 +149,7 @@ struct bnxt_re_ucontext {
 	struct bnxt_re_dev	*rdev;
 	struct bnxt_qplib_dpi	dpi;
 	struct bnxt_qplib_dpi   wcdpi;
+	struct mutex		wcdpi_lock;	/* serialises WC DPI alloc/free */
 	void			*shpg;
 	spinlock_t		sh_lock;	/* protect shpg */
 	struct rdma_user_mmap_entry *shpage_mmap;
diff --git a/drivers/infiniband/hw/bnxt_re/uapi.c b/drivers/infiniband/hw/bnxt_re/uapi.c
index ae8f46ab6961..b5e4cf62b63e 100644
--- a/drivers/infiniband/hw/bnxt_re/uapi.c
+++ b/drivers/infiniband/hw/bnxt_re/uapi.c
@@ -104,14 +104,23 @@ static int UVERBS_HANDLER(BNXT_RE_METHOD_ALLOC_PAGE)(struct uverbs_attr_bundle *
 
 	switch (alloc_type) {
 	case BNXT_RE_ALLOC_WC_PAGE:
-		if (cctx->modes.db_push)  {
+		if (cctx->modes.db_push) {
+			mutex_lock(&uctx->wcdpi_lock);
+			/* already allocated — one WC page per context */
+			if (uctx->wcdpi.dbr) {
+				mutex_unlock(&uctx->wcdpi_lock);
+				return -EEXIST;
+			}
 			if (bnxt_qplib_alloc_dpi(&rdev->qplib_res, &uctx->wcdpi,
-						 uctx, BNXT_QPLIB_DPI_TYPE_WC))
+						 uctx, BNXT_QPLIB_DPI_TYPE_WC)) {
+				mutex_unlock(&uctx->wcdpi_lock);
 				return -ENOMEM;
+			}
 			length = PAGE_SIZE;
 			dpi = uctx->wcdpi.dpi;
 			addr = (u64)uctx->wcdpi.umdbr;
 			mmap_flag = BNXT_RE_MMAP_WC_DB;
+			mutex_unlock(&uctx->wcdpi_lock);
 		} else {
 			return -EINVAL;
 		}
@@ -134,8 +143,15 @@ static int UVERBS_HANDLER(BNXT_RE_METHOD_ALLOC_PAGE)(struct uverbs_attr_bundle *
 	}
 
 	entry = bnxt_re_mmap_entry_insert(uctx, addr, mmap_flag, &mmap_offset);
-	if (!entry)
+	if (!entry) {
+		if (mmap_flag == BNXT_RE_MMAP_WC_DB) {
+			mutex_lock(&uctx->wcdpi_lock);
+			bnxt_qplib_dealloc_dpi(&rdev->qplib_res, &uctx->wcdpi);
+			uctx->wcdpi.dbr = NULL;
+			mutex_unlock(&uctx->wcdpi_lock);
+		}
 		return -ENOMEM;
+	}
 
 	uobj->object = entry;
 	uverbs_finalize_uobj_create(attrs, BNXT_RE_ALLOC_PAGE_HANDLE);
@@ -166,11 +182,16 @@ static int alloc_page_obj_cleanup(struct ib_uobject *uobject,
 
 	switch (entry->mmap_flag) {
 	case BNXT_RE_MMAP_WC_DB:
-		if (uctx && uctx->wcdpi.dbr) {
+		if (uctx) {
 			struct bnxt_re_dev *rdev = uctx->rdev;
 
-			bnxt_qplib_dealloc_dpi(&rdev->qplib_res, &uctx->wcdpi);
-			uctx->wcdpi.dbr = NULL;
+			mutex_lock(&uctx->wcdpi_lock);
+			if (uctx->wcdpi.dbr) {
+				bnxt_qplib_dealloc_dpi(&rdev->qplib_res,
+						       &uctx->wcdpi);
+				uctx->wcdpi.dbr = NULL;
+			}
+			mutex_unlock(&uctx->wcdpi_lock);
 		}
 		break;
 	case BNXT_RE_MMAP_DBR_BAR:
-- 
2.39.3


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH rdma-rc v2 12/15] RDMA/bnxt_re: Fix the cleanup upon error during SRQ create
  2026-06-15 22:47 [PATCH rdma-rc v2 00/15] RDMA/bnxt_re: Generic driver fixes Selvin Xavier
                   ` (10 preceding siblings ...)
  2026-06-15 22:47 ` [PATCH rdma-rc v2 11/15] RDMA/bnxt_re: Avoid repeated requests to allocate WC pages Selvin Xavier
@ 2026-06-15 22:47 ` Selvin Xavier
  2026-06-15 22:47 ` [PATCH rdma-rc v2 13/15] RDMA/bnxt_re: Fix the cleanup upon error during CQ create Selvin Xavier
                   ` (2 subsequent siblings)
  14 siblings, 0 replies; 16+ messages in thread
From: Selvin Xavier @ 2026-06-15 22:47 UTC (permalink / raw)
  To: leon, jgg
  Cc: linux-rdma, andrew.gospodarek, kalesh-anakkur.purayil,
	sriharsha.basavapatna, Selvin Xavier

Fix the failure path of SRQ create. Destroy the SRQ from HW and delete
from the hashlist if the page allocation fails. Wait for any concurrent
bnxt_re_search_for_srq() caller to release the pointer before the RDMA
core frees the object. Also add an explicit check for NULL before calling
free_page.

Fixes: 181028a0d84c ("RDMA/bnxt_re: Share a page to expose per SRQ info with userspace")
Reviewed-by: Sriharsha Basavapatna <sriharsha.basavapatna@broadcom.com>
Signed-off-by: Selvin Xavier <selvin.xavier@broadcom.com>
---
 drivers/infiniband/hw/bnxt_re/ib_verbs.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.c b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
index dc546308b46e..33f212bab544 100644
--- a/drivers/infiniband/hw/bnxt_re/ib_verbs.c
+++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
@@ -2293,6 +2293,8 @@ int bnxt_re_create_srq(struct ib_srq *ib_srq,
 			srq->uctx_srq_page = (void *)get_zeroed_page(GFP_KERNEL);
 			if (!srq->uctx_srq_page) {
 				rc = -ENOMEM;
+				bnxt_qplib_destroy_srq(&rdev->qplib_res,
+						       &srq->qplib_srq);
 				goto fail;
 			}
 			resp.comp_mask |= BNXT_RE_SRQ_TOGGLE_PAGE_SUPPORT;
@@ -2312,6 +2314,19 @@ int bnxt_re_create_srq(struct ib_srq *ib_srq,
 	return 0;
 
 fail:
+	if (rdev->chip_ctx->modes.toggle_bits & BNXT_QPLIB_SRQ_TOGGLE_BIT && srq->uctx) {
+		mutex_lock(&rdev->srq_hash_lock);
+		hash_del(&srq->hash_entry);
+		mutex_unlock(&rdev->srq_hash_lock);
+		/* Drop the creator's reference and wait for any concurrent
+		 * bnxt_re_search_for_srq() caller to release the pointer
+		 * before the RDMA core frees the object.
+		 */
+		kref_put(&srq->srq_ref, bnxt_re_srq_release);
+		wait_for_completion(&srq->srq_destroy_comp);
+		if (srq->uctx_srq_page)
+			free_page((unsigned long)srq->uctx_srq_page);
+	}
 	ib_umem_release(srq->umem);
 exit:
 	return rc;
-- 
2.39.3


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH rdma-rc v2 13/15] RDMA/bnxt_re: Fix the cleanup upon error during CQ create
  2026-06-15 22:47 [PATCH rdma-rc v2 00/15] RDMA/bnxt_re: Generic driver fixes Selvin Xavier
                   ` (11 preceding siblings ...)
  2026-06-15 22:47 ` [PATCH rdma-rc v2 12/15] RDMA/bnxt_re: Fix the cleanup upon error during SRQ create Selvin Xavier
@ 2026-06-15 22:47 ` Selvin Xavier
  2026-06-15 22:47 ` [PATCH rdma-rc v2 14/15] RDMA/bnxt_re: Fail DBR related page allocation UAPIs if the feature is disabled Selvin Xavier
  2026-06-15 22:47 ` [PATCH rdma-rc v2 15/15] RDMA/bnxt_re: Reject GET_TOGGLE_MEM when toggle page was not allocated Selvin Xavier
  14 siblings, 0 replies; 16+ messages in thread
From: Selvin Xavier @ 2026-06-15 22:47 UTC (permalink / raw)
  To: leon, jgg
  Cc: linux-rdma, andrew.gospodarek, kalesh-anakkur.purayil,
	sriharsha.basavapatna, Selvin Xavier

Fix the failure path of CQ create. Destroy the CQ from HW and delete
from the hashlist if the page allocation fails. Also, add an explicit check
for NULL before calling free_page.

Fixes: e275919d9669 ("RDMA/bnxt_re: Share a page to expose per CQ info with userspace")
Reviewed-by: Sriharsha Basavapatna <sriharsha.basavapatna@broadcom.com>
Signed-off-by: Selvin Xavier <selvin.xavier@broadcom.com>
---
 drivers/infiniband/hw/bnxt_re/ib_verbs.c | 19 ++++++++++++++++---
 1 file changed, 16 insertions(+), 3 deletions(-)

diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.c b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
index 33f212bab544..0ebcb408b305 100644
--- a/drivers/infiniband/hw/bnxt_re/ib_verbs.c
+++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
@@ -3615,14 +3615,27 @@ int bnxt_re_create_user_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *att
 	resp.phase = cq->qplib_cq.period;
 	rc = ib_respond_udata(udata, resp);
 	if (rc)
-		goto free_mem;
+		goto free_page;
 
 	return 0;
 
-free_mem:
-	free_page((unsigned long)cq->uctx_cq_page);
+free_page:
+	if (cq->uctx_cq_page)
+		free_page((unsigned long)cq->uctx_cq_page);
+
 destroy_cq:
 	bnxt_qplib_destroy_cq(&rdev->qplib_res, &cq->qplib_cq);
+	if (cctx->modes.toggle_bits & BNXT_QPLIB_CQ_TOGGLE_BIT) {
+		mutex_lock(&rdev->cq_hash_lock);
+		hash_del(&cq->hash_entry);
+		mutex_unlock(&rdev->cq_hash_lock);
+		/* Drop the creator's reference and wait for any concurrent
+		 * bnxt_re_search_for_cq() caller to release the pointer
+		 * before the RDMA core frees the object.
+		 */
+		kref_put(&cq->cq_ref, bnxt_re_cq_release);
+		wait_for_completion(&cq->cq_destroy_comp);
+	}
 free_umem:
 	ib_umem_release(cq->umem);
 	return rc;
-- 
2.39.3


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH rdma-rc v2 14/15] RDMA/bnxt_re: Fail DBR related page allocation UAPIs if the feature is disabled
  2026-06-15 22:47 [PATCH rdma-rc v2 00/15] RDMA/bnxt_re: Generic driver fixes Selvin Xavier
                   ` (12 preceding siblings ...)
  2026-06-15 22:47 ` [PATCH rdma-rc v2 13/15] RDMA/bnxt_re: Fix the cleanup upon error during CQ create Selvin Xavier
@ 2026-06-15 22:47 ` Selvin Xavier
  2026-06-15 22:47 ` [PATCH rdma-rc v2 15/15] RDMA/bnxt_re: Reject GET_TOGGLE_MEM when toggle page was not allocated Selvin Xavier
  14 siblings, 0 replies; 16+ messages in thread
From: Selvin Xavier @ 2026-06-15 22:47 UTC (permalink / raw)
  To: leon, jgg
  Cc: linux-rdma, andrew.gospodarek, kalesh-anakkur.purayil,
	sriharsha.basavapatna, Selvin Xavier

No need to support the DBR related page allocations if the pacing feature
is disabled. Fail the request if pacing is disabled.

Fixes: ea2224857882 ("RDMA/bnxt_re: Update alloc_page uapi for pacing")
Reviewed-by: Sriharsha Basavapatna <sriharsha.basavapatna@broadcom.com>
Signed-off-by: Selvin Xavier <selvin.xavier@broadcom.com>
---
 drivers/infiniband/hw/bnxt_re/uapi.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/infiniband/hw/bnxt_re/uapi.c b/drivers/infiniband/hw/bnxt_re/uapi.c
index b5e4cf62b63e..ef41d6a1a0bb 100644
--- a/drivers/infiniband/hw/bnxt_re/uapi.c
+++ b/drivers/infiniband/hw/bnxt_re/uapi.c
@@ -127,12 +127,16 @@ static int UVERBS_HANDLER(BNXT_RE_METHOD_ALLOC_PAGE)(struct uverbs_attr_bundle *
 
 		break;
 	case BNXT_RE_ALLOC_DBR_BAR_PAGE:
+		if (!rdev->pacing.dbr_pacing)
+			return -EOPNOTSUPP;
 		length = PAGE_SIZE;
 		addr = (u64)rdev->pacing.dbr_bar_addr;
 		mmap_flag = BNXT_RE_MMAP_DBR_BAR;
 		break;
 
 	case BNXT_RE_ALLOC_DBR_PAGE:
+		if (!rdev->pacing.dbr_pacing)
+			return -EOPNOTSUPP;
 		length = PAGE_SIZE;
 		addr = (u64)rdev->pacing.dbr_page;
 		mmap_flag = BNXT_RE_MMAP_DBR_PAGE;
-- 
2.39.3


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH rdma-rc v2 15/15] RDMA/bnxt_re: Reject GET_TOGGLE_MEM when toggle page was not allocated
  2026-06-15 22:47 [PATCH rdma-rc v2 00/15] RDMA/bnxt_re: Generic driver fixes Selvin Xavier
                   ` (13 preceding siblings ...)
  2026-06-15 22:47 ` [PATCH rdma-rc v2 14/15] RDMA/bnxt_re: Fail DBR related page allocation UAPIs if the feature is disabled Selvin Xavier
@ 2026-06-15 22:47 ` Selvin Xavier
  14 siblings, 0 replies; 16+ messages in thread
From: Selvin Xavier @ 2026-06-15 22:47 UTC (permalink / raw)
  To: leon, jgg
  Cc: linux-rdma, andrew.gospodarek, kalesh-anakkur.purayil,
	sriharsha.basavapatna, Selvin Xavier

If a user calls BNXT_RE_METHOD_GET_TOGGLE_MEM on a device that does not
support the CQ/SRQ toggle feature, uctx_cq_page or uctx_srq_page will
be NULL.

Add an explicit -EOPNOTSUPP return after capturing the address from
uctx_cq_page / uctx_srq_page if the address is zero.

Fixes: e275919d9669 ("RDMA/bnxt_re: Share a page to expose per CQ info with userspace")
Fixes: 181028a0d84c ("RDMA/bnxt_re: Share a page to expose per SRQ info with userspace")
Signed-off-by: Selvin Xavier <selvin.xavier@broadcom.com>
---
 drivers/infiniband/hw/bnxt_re/uapi.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/infiniband/hw/bnxt_re/uapi.c b/drivers/infiniband/hw/bnxt_re/uapi.c
index ef41d6a1a0bb..37997c36c6f8 100644
--- a/drivers/infiniband/hw/bnxt_re/uapi.c
+++ b/drivers/infiniband/hw/bnxt_re/uapi.c
@@ -289,6 +289,8 @@ static int UVERBS_HANDLER(BNXT_RE_METHOD_GET_TOGGLE_MEM)(struct uverbs_attr_bund
 
 		addr = (u64)cq->uctx_cq_page;
 		bnxt_re_put_cq(cq);
+		if (!addr)
+			return -EOPNOTSUPP;
 		break;
 	case BNXT_RE_SRQ_TOGGLE_MEM:
 		srq = bnxt_re_search_for_srq(rdev, res_id);
@@ -302,6 +304,8 @@ static int UVERBS_HANDLER(BNXT_RE_METHOD_GET_TOGGLE_MEM)(struct uverbs_attr_bund
 
 		addr = (u64)srq->uctx_srq_page;
 		bnxt_re_put_srq(srq);
+		if (!addr)
+			return -EOPNOTSUPP;
 		break;
 
 	default:
-- 
2.39.3


^ permalink raw reply related	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2026-06-15 17:26 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-15 22:47 [PATCH rdma-rc v2 00/15] RDMA/bnxt_re: Generic driver fixes Selvin Xavier
2026-06-15 22:47 ` [PATCH rdma-rc v2 01/15] RDMA/bnxt_re: Initialize dpi variable to zero Selvin Xavier
2026-06-15 22:47 ` [PATCH rdma-rc v2 02/15] RDMA/bnxt_re: Free SRQ toggle page after firmware teardown Selvin Xavier
2026-06-15 22:47 ` [PATCH rdma-rc v2 03/15] RDMA/bnxt_re: Free CQ " Selvin Xavier
2026-06-15 22:47 ` [PATCH rdma-rc v2 04/15] RDMA/bnxt_re: Avoid any race while handling the hash list of CQ Selvin Xavier
2026-06-15 22:47 ` [PATCH rdma-rc v2 05/15] RDMA/bnxt_re: Avoid any race while handling the hash list of SRQ Selvin Xavier
2026-06-15 22:47 ` [PATCH rdma-rc v2 06/15] RDMA/bnxt_re: Add ownership check while getting the CQ toggle page Selvin Xavier
2026-06-15 22:47 ` [PATCH rdma-rc v2 07/15] RDMA/bnxt_re: Add ownership check while getting the SRQ " Selvin Xavier
2026-06-15 22:47 ` [PATCH rdma-rc v2 08/15] RDMA/bnxt_re: Avoid displaying the kernel pointer Selvin Xavier
2026-06-15 22:47 ` [PATCH rdma-rc v2 09/15] RDMA/bnxt_re: Add a max slot check for SQ Selvin Xavier
2026-06-15 22:47 ` [PATCH rdma-rc v2 10/15] RDMA/bnxt_re: Proper rollback if the ioremap fails Selvin Xavier
2026-06-15 22:47 ` [PATCH rdma-rc v2 11/15] RDMA/bnxt_re: Avoid repeated requests to allocate WC pages Selvin Xavier
2026-06-15 22:47 ` [PATCH rdma-rc v2 12/15] RDMA/bnxt_re: Fix the cleanup upon error during SRQ create Selvin Xavier
2026-06-15 22:47 ` [PATCH rdma-rc v2 13/15] RDMA/bnxt_re: Fix the cleanup upon error during CQ create Selvin Xavier
2026-06-15 22:47 ` [PATCH rdma-rc v2 14/15] RDMA/bnxt_re: Fail DBR related page allocation UAPIs if the feature is disabled Selvin Xavier
2026-06-15 22:47 ` [PATCH rdma-rc v2 15/15] RDMA/bnxt_re: Reject GET_TOGGLE_MEM when toggle page was not allocated Selvin Xavier

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox