Linux RDMA and InfiniBand development
 help / color / mirror / Atom feed
* [PATCH rdma-next v6 0/9] RDMA/bnxt_re: Support QP uapi extensions
@ 2026-05-18 15:37 Sriharsha Basavapatna
  2026-05-18 15:37 ` [PATCH rdma-next v6 1/9] RDMA/bnxt_re: Refactor bnxt_re_init_user_qp() Sriharsha Basavapatna
                   ` (8 more replies)
  0 siblings, 9 replies; 17+ messages in thread
From: Sriharsha Basavapatna @ 2026-05-18 15:37 UTC (permalink / raw)
  To: leon, jgg
  Cc: linux-rdma, andrew.gospodarek, selvin.xavier,
	kalesh-anakkur.purayil, Sriharsha Basavapatna

Hi,

This patchset adds QP uapi extensions to the bnxt_re driver.
This is required by applications that need to manage some of the
RDMA HW resources directly and to implement the datapath in the
application.

This series supports application allocated memory for QPs.
The application takes into account SQ/RQ ring sizing constraints
(extra entries, rounding up etc) while allocating this memory.
The driver should avoid duplicating this logic while creating
these QPs.

uAPI changes in this series:
- Patch#4: new uapi parameter 'sq_npsn' in bnxt_re_qp_req.
- Patch#8: new driver specific attribute 'DBR_HANDLE' for doorbell region.
- Patch#9: new comp_mask 'FIXED_QUE_ATTR' in bnxt_re_qp_req.

Patch#1 Refactor bnxt_re_init_user_qp()
Patch#2 Update rq depth for app allocated QPs
Patch#3 Update sq depth for app allocated QPs
Patch#4 Update msn table size for app allocated QPs
Patch#5 Update hwq depth for app allocated QPs
Patch#6 Enhance dbr usecnt logic in doorbell uapis
Patch#7 Enhance dpi lifecycle logic in doorbell uapis
Patch#8 Support doorbells for app allocated QPs
Patch#9 Enable app allocated QPs 

Thanks,
-Harsha

******

Changes:

v6:
- Fixed issues reported by Sashiko AI.
- Added two new patches: #6 and #7.
- Patch#6: Support kref for DBR object (from v5).
- Patch#7: DPI lifecycle changes.
- Patch#8 (QP-DBR) requires these two patches.
- Patch#9:
  - Commit msg updated: removed unused comp_mask.
  - ureq->sq_npsn validation (from v5).
- Remaining issues are about lack of ureq->sq_slots validation.
  - Existing code; will be fixed in a subsequent patch series.

v5:
- Fixed issues reported by Sashiko AI.
- Patch#1:
  - No changes.
  - Issues are about lack of ureq->sq_slots validation.
  - Existing code; will be fixed in a subsequent patch series.
- Patch#2:
  - Removed unused ureq param in bnxt_re_init_rq_attr().
- Patch#4:
  - Issues are about lack of ureq->sq_npsn validation.
  - Validation added in Patch#7 fixes these issues.
- Patch#5:
  - Updated to utilize existing code for RQ hwq depth.
- Patch#6:
  - Moved usecnt relase logic to after QP is destroyed in HW.
  - Avoids race with concurrent dbr destroy.
  - Updated usecnt from simple atomic to kref based counter.
  - This handles implicit teardown of dbr.
  - Added kfree() of dbr.
- Patch#7:
  - Added validation of ureq->sq_npsn.
  - Removed unused ureq comp_mask: BNXT_RE_QP_REQ_MASK_VAR_WQE_SQ_SLOTS.

v4:
- Rebased to latest for-next tree (Linux 7.1-rc1, commit: 254f49634ee1).
- Renamed QP req comp_mask: APP_ALLOCATED_QP_ENABLE -> FIXED_QUE_ATTR.

v3:
- Removed umem patch from the series, that is dependent on uverbs support.
- Patch#7: Process DBR_HANDLE attr regardless of app_qp comp_mask.

v2:
- Rebased to umem_list uverbs patch series:
  https://patchwork.kernel.org/project/linux-rdma/cover/20260325150048.168341-1-jiri@resnulli.us/
- Deleted Patch#9; create_qp_umem devop is not supported.

v5: https://lore.kernel.org/linux-rdma/20260514162336.72644-1-sriharsha.basavapatna@broadcom.com/
v4: https://lore.kernel.org/linux-rdma/20260508085858.21060-1-sriharsha.basavapatna@broadcom.com/
v3: https://lore.kernel.org/linux-rdma/20260415054957.36745-1-sriharsha.basavapatna@broadcom.com/
v2: https://lore.kernel.org/linux-rdma/20260327091755.47754-1-sriharsha.basavapatna@broadcom.com/
v1: https://lore.kernel.org/linux-rdma/20260320135437.48716-1-sriharsha.basavapatna@broadcom.com/

******

Sriharsha Basavapatna (9):
  RDMA/bnxt_re: Refactor bnxt_re_init_user_qp()
  RDMA/bnxt_re: Update rq depth for app allocated QPs
  RDMA/bnxt_re: Update sq depth for app allocated QPs
  RDMA/bnxt_re: Update msn table size for app allocated QPs
  RDMA/bnxt_re: Update hwq depth for app allocated QPs
  RDMA/bnxt_re: Enhance dbr usecnt logic in doorbell uapis
  RDMA/bnxt_re: Enhance dpi lifecycle logic in doorbell uapis
  RDMA/bnxt_re: Support doorbells for app allocated QPs
  RDMA/bnxt_re: Enable app allocated QPs

 drivers/infiniband/hw/bnxt_re/ib_verbs.c | 273 +++++++++++++++--------
 drivers/infiniband/hw/bnxt_re/ib_verbs.h |   5 +-
 drivers/infiniband/hw/bnxt_re/uapi.c     |  48 +++-
 include/uapi/rdma/bnxt_re-abi.h          |   7 +-
 4 files changed, 240 insertions(+), 93 deletions(-)

-- 
2.51.2.636.ga99f379adf


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

* [PATCH rdma-next v6 1/9] RDMA/bnxt_re: Refactor bnxt_re_init_user_qp()
  2026-05-18 15:37 [PATCH rdma-next v6 0/9] RDMA/bnxt_re: Support QP uapi extensions Sriharsha Basavapatna
@ 2026-05-18 15:37 ` Sriharsha Basavapatna
  2026-05-18 15:37 ` [PATCH rdma-next v6 2/9] RDMA/bnxt_re: Update rq depth for app allocated QPs Sriharsha Basavapatna
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 17+ messages in thread
From: Sriharsha Basavapatna @ 2026-05-18 15:37 UTC (permalink / raw)
  To: leon, jgg
  Cc: linux-rdma, andrew.gospodarek, selvin.xavier,
	kalesh-anakkur.purayil, Sriharsha Basavapatna

The umem changes for CQ added a helper - bnxt_re_setup_sginfo().
Use the same helper for QP creation since we support only 4K
pages for QP ring memory too.

Add a new helper function bnxt_re_get_psn_bytes() to improve
readability as this code will be updated in subsequent patches.

Signed-off-by: Sriharsha Basavapatna <sriharsha.basavapatna@broadcom.com>
Reviewed-by: Selvin Xavier <selvin.xavier@broadcom.com>
---
 drivers/infiniband/hw/bnxt_re/ib_verbs.c | 127 +++++++++++++----------
 1 file changed, 73 insertions(+), 54 deletions(-)

diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.c b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
index 7ed294516b7e..561d491f12ff 100644
--- a/drivers/infiniband/hw/bnxt_re/ib_verbs.c
+++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
@@ -1136,34 +1136,64 @@ static int bnxt_re_setup_swqe_size(struct bnxt_re_qp *qp,
 	return 0;
 }
 
+static int bnxt_re_setup_sginfo(struct bnxt_re_dev *rdev,
+				struct ib_umem *umem,
+				struct bnxt_qplib_sg_info *sginfo)
+{
+	unsigned long page_size;
+
+	if (!umem)
+		return -EINVAL;
+
+	page_size = ib_umem_find_best_pgsz(umem, SZ_4K, 0);
+	if (!page_size || page_size != SZ_4K)
+		return -EINVAL;
+
+	sginfo->umem = umem;
+	sginfo->npages = ib_umem_num_dma_blocks(umem, page_size);
+	sginfo->pgsize = page_size;
+	sginfo->pgshft = __builtin_ctz(page_size);
+	return 0;
+}
+
+static int bnxt_re_get_psn_bytes(struct bnxt_re_dev *rdev,
+				 struct bnxt_re_ucontext *cntx,
+				 struct bnxt_qplib_qp *qplib_qp,
+				 struct bnxt_re_qp_req *ureq)
+{
+	int psn_sz, psn_nume;
+
+	psn_sz = bnxt_qplib_is_chip_gen_p5_p7(rdev->chip_ctx) ?
+				sizeof(struct sq_psn_search_ext) :
+				sizeof(struct sq_psn_search);
+	if (cntx && bnxt_re_is_var_size_supported(rdev, cntx)) {
+		psn_nume = ureq->sq_slots;
+	} else {
+		psn_nume = (qplib_qp->wqe_mode == BNXT_QPLIB_WQE_MODE_STATIC) ?
+		qplib_qp->sq.max_wqe : ((qplib_qp->sq.max_wqe * qplib_qp->sq.wqe_size) /
+			 sizeof(struct bnxt_qplib_sge));
+	}
+	if (_is_host_msn_table(rdev->qplib_res.dattr->dev_cap_flags2))
+		psn_nume = roundup_pow_of_two(psn_nume);
+
+	return psn_nume * psn_sz;
+}
+
 static int bnxt_re_init_user_qp(struct bnxt_re_dev *rdev, struct bnxt_re_pd *pd,
 				struct bnxt_re_qp *qp, struct bnxt_re_ucontext *cntx,
 				struct bnxt_re_qp_req *ureq)
 {
 	struct bnxt_qplib_qp *qplib_qp;
-	int bytes = 0, psn_sz;
 	struct ib_umem *umem;
-	int psn_nume;
+	int bytes;
+	int rc;
 
 	qplib_qp = &qp->qplib_qp;
 
 	bytes = (qplib_qp->sq.max_wqe * qplib_qp->sq.wqe_size);
 	/* Consider mapping PSN search memory only for RC QPs. */
-	if (qplib_qp->type == CMDQ_CREATE_QP_TYPE_RC) {
-		psn_sz = bnxt_qplib_is_chip_gen_p5_p7(rdev->chip_ctx) ?
-						   sizeof(struct sq_psn_search_ext) :
-						   sizeof(struct sq_psn_search);
-		if (cntx && bnxt_re_is_var_size_supported(rdev, cntx)) {
-			psn_nume = ureq->sq_slots;
-		} else {
-			psn_nume = (qplib_qp->wqe_mode == BNXT_QPLIB_WQE_MODE_STATIC) ?
-			qplib_qp->sq.max_wqe : ((qplib_qp->sq.max_wqe * qplib_qp->sq.wqe_size) /
-				 sizeof(struct bnxt_qplib_sge));
-		}
-		if (_is_host_msn_table(rdev->qplib_res.dattr->dev_cap_flags2))
-			psn_nume = roundup_pow_of_two(psn_nume);
-		bytes += (psn_nume * psn_sz);
-	}
+	if (qplib_qp->type == CMDQ_CREATE_QP_TYPE_RC)
+		bytes += bnxt_re_get_psn_bytes(rdev, cntx, qplib_qp, ureq);
 
 	bytes = PAGE_ALIGN(bytes);
 	umem = ib_umem_get(&rdev->ibdev, ureq->qpsva, bytes,
@@ -1172,33 +1202,42 @@ static int bnxt_re_init_user_qp(struct bnxt_re_dev *rdev, struct bnxt_re_pd *pd,
 		return PTR_ERR(umem);
 
 	qp->sumem = umem;
-	qplib_qp->sq.sg_info.umem = umem;
-	qplib_qp->sq.sg_info.pgsize = PAGE_SIZE;
-	qplib_qp->sq.sg_info.pgshft = PAGE_SHIFT;
-	qplib_qp->qp_handle = ureq->qp_handle;
+	rc = bnxt_re_setup_sginfo(rdev, qp->sumem, &qplib_qp->sq.sg_info);
+	if (rc)
+		goto fail;
+
+	if (qp->qplib_qp.srq)
+		goto done;
 
-	if (!qp->qplib_qp.srq) {
-		bytes = (qplib_qp->rq.max_wqe * qplib_qp->rq.wqe_size);
-		bytes = PAGE_ALIGN(bytes);
-		umem = ib_umem_get(&rdev->ibdev, ureq->qprva, bytes,
-				   IB_ACCESS_LOCAL_WRITE);
-		if (IS_ERR(umem))
-			goto rqfail;
-		qp->rumem = umem;
-		qplib_qp->rq.sg_info.umem = umem;
-		qplib_qp->rq.sg_info.pgsize = PAGE_SIZE;
-		qplib_qp->rq.sg_info.pgshft = PAGE_SHIFT;
+	bytes = (qplib_qp->rq.max_wqe * qplib_qp->rq.wqe_size);
+	bytes = PAGE_ALIGN(bytes);
+	umem = ib_umem_get(&rdev->ibdev, ureq->qprva, bytes,
+			   IB_ACCESS_LOCAL_WRITE);
+	if (IS_ERR(umem)) {
+		rc = PTR_ERR(umem);
+		goto fail;
 	}
 
+	qp->rumem = umem;
+	rc = bnxt_re_setup_sginfo(rdev, qp->rumem, &qplib_qp->rq.sg_info);
+	if (rc)
+		goto rqfail;
+
+done:
+	qplib_qp->qp_handle = ureq->qp_handle;
 	qplib_qp->dpi = &cntx->dpi;
 	qplib_qp->is_user = true;
 	return 0;
+
 rqfail:
+	ib_umem_release(qp->rumem);
+	qp->rumem = NULL;
+	memset(&qplib_qp->rq.sg_info, 0, sizeof(qplib_qp->rq.sg_info));
+fail:
 	ib_umem_release(qp->sumem);
 	qp->sumem = NULL;
 	memset(&qplib_qp->sq.sg_info, 0, sizeof(qplib_qp->sq.sg_info));
-
-	return PTR_ERR(umem);
+	return rc;
 }
 
 static struct bnxt_re_ah *bnxt_re_create_shadow_qp_ah
@@ -3345,26 +3384,6 @@ int bnxt_re_destroy_cq(struct ib_cq *ib_cq, struct ib_udata *udata)
 	return ib_respond_empty_udata(udata);
 }
 
-static int bnxt_re_setup_sginfo(struct bnxt_re_dev *rdev,
-				struct ib_umem *umem,
-				struct bnxt_qplib_sg_info *sginfo)
-{
-	unsigned long page_size;
-
-	if (!umem)
-		return -EINVAL;
-
-	page_size = ib_umem_find_best_pgsz(umem, SZ_4K, 0);
-	if (!page_size || page_size != SZ_4K)
-		return -EINVAL;
-
-	sginfo->umem = umem;
-	sginfo->npages = ib_umem_num_dma_blocks(umem, page_size);
-	sginfo->pgsize = page_size;
-	sginfo->pgshft = __builtin_ctz(page_size);
-	return 0;
-}
-
 int bnxt_re_create_user_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr,
 			   struct uverbs_attr_bundle *attrs)
 {
-- 
2.51.2.636.ga99f379adf


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

* [PATCH rdma-next v6 2/9] RDMA/bnxt_re: Update rq depth for app allocated QPs
  2026-05-18 15:37 [PATCH rdma-next v6 0/9] RDMA/bnxt_re: Support QP uapi extensions Sriharsha Basavapatna
  2026-05-18 15:37 ` [PATCH rdma-next v6 1/9] RDMA/bnxt_re: Refactor bnxt_re_init_user_qp() Sriharsha Basavapatna
@ 2026-05-18 15:37 ` Sriharsha Basavapatna
  2026-05-18 15:37 ` [PATCH rdma-next v6 3/9] RDMA/bnxt_re: Update sq " Sriharsha Basavapatna
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 17+ messages in thread
From: Sriharsha Basavapatna @ 2026-05-18 15:37 UTC (permalink / raw)
  To: leon, jgg
  Cc: linux-rdma, andrew.gospodarek, selvin.xavier,
	kalesh-anakkur.purayil, Sriharsha Basavapatna

For app allocated QPs, there's no need to add extra slots or
to round up the slot count. Use 'max_recv_wr' count provided
by the application as is.

Signed-off-by: Sriharsha Basavapatna <sriharsha.basavapatna@broadcom.com>
Reviewed-by: Selvin Xavier <selvin.xavier@broadcom.com>
---
 drivers/infiniband/hw/bnxt_re/ib_verbs.c | 22 ++++++++++++++--------
 1 file changed, 14 insertions(+), 8 deletions(-)

diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.c b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
index 561d491f12ff..c67179160654 100644
--- a/drivers/infiniband/hw/bnxt_re/ib_verbs.c
+++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
@@ -1475,7 +1475,8 @@ static struct bnxt_re_qp *bnxt_re_create_shadow_qp
 
 static int bnxt_re_init_rq_attr(struct bnxt_re_qp *qp,
 				struct ib_qp_init_attr *init_attr,
-				struct bnxt_re_ucontext *uctx)
+				struct bnxt_re_ucontext *uctx,
+				bool fixed_que_attr)
 {
 	struct bnxt_qplib_dev_attr *dev_attr;
 	struct bnxt_qplib_qp *qplqp;
@@ -1500,12 +1501,16 @@ static int bnxt_re_init_rq_attr(struct bnxt_re_qp *qp,
 		init_attr->cap.max_recv_sge = rq->max_sge;
 		rq->wqe_size = bnxt_re_setup_rwqe_size(qplqp, rq->max_sge,
 						       dev_attr->max_qp_sges);
-		/* Allocate 1 more than what's provided so posting max doesn't
-		 * mean empty.
-		 */
-		rq->max_wqe = bnxt_re_init_depth(init_attr->cap.max_recv_wr + 1,
-						 dev_attr->max_qp_wqes + 1,
-						 uctx);
+		if (!fixed_que_attr) {
+			/* Allocate 1 more than what's provided so posting max doesn't
+			 * mean empty.
+			 */
+			rq->max_wqe = bnxt_re_init_depth(init_attr->cap.max_recv_wr + 1,
+							 dev_attr->max_qp_wqes + 1,
+							 uctx);
+		} else {
+			rq->max_wqe = init_attr->cap.max_recv_wr;
+		}
 		rq->max_sw_wqe = rq->max_wqe;
 		rq->q_full_delta = 0;
 		rq->sg_info.pgsize = PAGE_SIZE;
@@ -1676,6 +1681,7 @@ static int bnxt_re_init_qp_attr(struct bnxt_re_qp *qp, struct bnxt_re_pd *pd,
 {
 	struct bnxt_qplib_dev_attr *dev_attr;
 	struct bnxt_qplib_qp *qplqp;
+	bool fixed_que_attr = false;
 	struct bnxt_re_dev *rdev;
 	struct bnxt_re_cq *cq;
 	int rc = 0, qptype;
@@ -1724,7 +1730,7 @@ static int bnxt_re_init_qp_attr(struct bnxt_re_qp *qp, struct bnxt_re_pd *pd,
 	}
 
 	/* Setup RQ/SRQ */
-	rc = bnxt_re_init_rq_attr(qp, init_attr, uctx);
+	rc = bnxt_re_init_rq_attr(qp, init_attr, uctx, fixed_que_attr);
 	if (rc)
 		return rc;
 	if (init_attr->qp_type == IB_QPT_GSI)
-- 
2.51.2.636.ga99f379adf


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

* [PATCH rdma-next v6 3/9] RDMA/bnxt_re: Update sq depth for app allocated QPs
  2026-05-18 15:37 [PATCH rdma-next v6 0/9] RDMA/bnxt_re: Support QP uapi extensions Sriharsha Basavapatna
  2026-05-18 15:37 ` [PATCH rdma-next v6 1/9] RDMA/bnxt_re: Refactor bnxt_re_init_user_qp() Sriharsha Basavapatna
  2026-05-18 15:37 ` [PATCH rdma-next v6 2/9] RDMA/bnxt_re: Update rq depth for app allocated QPs Sriharsha Basavapatna
@ 2026-05-18 15:37 ` Sriharsha Basavapatna
  2026-05-18 15:37 ` [PATCH rdma-next v6 4/9] RDMA/bnxt_re: Update msn table size " Sriharsha Basavapatna
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 17+ messages in thread
From: Sriharsha Basavapatna @ 2026-05-18 15:37 UTC (permalink / raw)
  To: leon, jgg
  Cc: linux-rdma, andrew.gospodarek, selvin.xavier,
	kalesh-anakkur.purayil, Sriharsha Basavapatna

For app allocated QPs, there's no need to reserve extra slots.
The application accounts for this while allocating the SQ.

Signed-off-by: Sriharsha Basavapatna <sriharsha.basavapatna@broadcom.com>
Reviewed-by: Selvin Xavier <selvin.xavier@broadcom.com>
---
 drivers/infiniband/hw/bnxt_re/ib_verbs.c | 24 +++++++++++++++---------
 1 file changed, 15 insertions(+), 9 deletions(-)

diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.c b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
index c67179160654..fd1ea053d563 100644
--- a/drivers/infiniband/hw/bnxt_re/ib_verbs.c
+++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
@@ -1541,7 +1541,8 @@ static void bnxt_re_adjust_gsi_rq_attr(struct bnxt_re_qp *qp)
 static int bnxt_re_init_sq_attr(struct bnxt_re_qp *qp,
 				struct ib_qp_init_attr *init_attr,
 				struct bnxt_re_ucontext *uctx,
-				struct bnxt_re_qp_req *ureq)
+				struct bnxt_re_qp_req *ureq,
+				bool fixed_que_attr)
 {
 	struct bnxt_qplib_dev_attr *dev_attr;
 	struct bnxt_qplib_qp *qplqp;
@@ -1582,13 +1583,18 @@ static int bnxt_re_init_sq_attr(struct bnxt_re_qp *qp,
 			sq->max_sw_wqe = sq->max_wqe;
 
 	}
-	sq->q_full_delta = diff + 1;
-	/*
-	 * Reserving one slot for Phantom WQE. Application can
-	 * post one extra entry in this case. But allowing this to avoid
-	 * unexpected Queue full condition
-	 */
-	qplqp->sq.q_full_delta -= 1;
+	if (!fixed_que_attr) {
+		sq->q_full_delta = diff + 1;
+		/*
+		 * Reserving one slot for Phantom WQE. Application can
+		 * post one extra entry in this case. But allowing this to avoid
+		 * unexpected Queue full condition
+		 */
+		qplqp->sq.q_full_delta -= 1;
+	} else {
+		sq->q_full_delta = 0;
+	}
+
 	qplqp->sq.sg_info.pgsize = PAGE_SIZE;
 	qplqp->sq.sg_info.pgshft = PAGE_SHIFT;
 
@@ -1737,7 +1743,7 @@ static int bnxt_re_init_qp_attr(struct bnxt_re_qp *qp, struct bnxt_re_pd *pd,
 		bnxt_re_adjust_gsi_rq_attr(qp);
 
 	/* Setup SQ */
-	rc = bnxt_re_init_sq_attr(qp, init_attr, uctx, ureq);
+	rc = bnxt_re_init_sq_attr(qp, init_attr, uctx, ureq, fixed_que_attr);
 	if (rc)
 		return rc;
 	if (init_attr->qp_type == IB_QPT_GSI)
-- 
2.51.2.636.ga99f379adf


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

* [PATCH rdma-next v6 4/9] RDMA/bnxt_re: Update msn table size for app allocated QPs
  2026-05-18 15:37 [PATCH rdma-next v6 0/9] RDMA/bnxt_re: Support QP uapi extensions Sriharsha Basavapatna
                   ` (2 preceding siblings ...)
  2026-05-18 15:37 ` [PATCH rdma-next v6 3/9] RDMA/bnxt_re: Update sq " Sriharsha Basavapatna
@ 2026-05-18 15:37 ` Sriharsha Basavapatna
  2026-05-18 15:37 ` [PATCH rdma-next v6 5/9] RDMA/bnxt_re: Update hwq depth " Sriharsha Basavapatna
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 17+ messages in thread
From: Sriharsha Basavapatna @ 2026-05-18 15:37 UTC (permalink / raw)
  To: leon, jgg
  Cc: linux-rdma, andrew.gospodarek, selvin.xavier,
	kalesh-anakkur.purayil, Sriharsha Basavapatna

For app allocated QPs, the driver shouldn't use slots/round-up logic
to compute the msn table size. The application handles this logic
and computes 'sq_npsn' and passes it to the driver using a new uapi
parameter.

Signed-off-by: Sriharsha Basavapatna <sriharsha.basavapatna@broadcom.com>
Reviewed-by: Selvin Xavier <selvin.xavier@broadcom.com>
---
 drivers/infiniband/hw/bnxt_re/ib_verbs.c | 61 +++++++++++++++---------
 include/uapi/rdma/bnxt_re-abi.h          |  1 +
 2 files changed, 40 insertions(+), 22 deletions(-)

diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.c b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
index fd1ea053d563..ae32f86b9e9b 100644
--- a/drivers/infiniband/hw/bnxt_re/ib_verbs.c
+++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
@@ -1159,29 +1159,39 @@ static int bnxt_re_setup_sginfo(struct bnxt_re_dev *rdev,
 static int bnxt_re_get_psn_bytes(struct bnxt_re_dev *rdev,
 				 struct bnxt_re_ucontext *cntx,
 				 struct bnxt_qplib_qp *qplib_qp,
-				 struct bnxt_re_qp_req *ureq)
+				 struct bnxt_re_qp_req *ureq,
+				 bool fixed_que_attr)
 {
 	int psn_sz, psn_nume;
 
-	psn_sz = bnxt_qplib_is_chip_gen_p5_p7(rdev->chip_ctx) ?
-				sizeof(struct sq_psn_search_ext) :
-				sizeof(struct sq_psn_search);
-	if (cntx && bnxt_re_is_var_size_supported(rdev, cntx)) {
-		psn_nume = ureq->sq_slots;
+	if (rdev->dev_attr &&
+	    _is_host_msn_table(rdev->dev_attr->dev_cap_flags2))
+		psn_sz = sizeof(struct sq_msn_search);
+	else
+		psn_sz = bnxt_qplib_is_chip_gen_p5_p7(rdev->chip_ctx) ?
+					sizeof(struct sq_psn_search_ext) :
+					sizeof(struct sq_psn_search);
+	if (!fixed_que_attr) {
+		if (cntx && bnxt_re_is_var_size_supported(rdev, cntx)) {
+			psn_nume = ureq->sq_slots;
+		} else {
+			psn_nume = (qplib_qp->wqe_mode == BNXT_QPLIB_WQE_MODE_STATIC) ?
+			qplib_qp->sq.max_wqe : ((qplib_qp->sq.max_wqe * qplib_qp->sq.wqe_size) /
+				 sizeof(struct bnxt_qplib_sge));
+		}
+		if (_is_host_msn_table(rdev->qplib_res.dattr->dev_cap_flags2))
+			psn_nume = roundup_pow_of_two(psn_nume);
 	} else {
-		psn_nume = (qplib_qp->wqe_mode == BNXT_QPLIB_WQE_MODE_STATIC) ?
-		qplib_qp->sq.max_wqe : ((qplib_qp->sq.max_wqe * qplib_qp->sq.wqe_size) /
-			 sizeof(struct bnxt_qplib_sge));
+		psn_nume = ureq->sq_npsn;
 	}
-	if (_is_host_msn_table(rdev->qplib_res.dattr->dev_cap_flags2))
-		psn_nume = roundup_pow_of_two(psn_nume);
 
 	return psn_nume * psn_sz;
 }
 
 static int bnxt_re_init_user_qp(struct bnxt_re_dev *rdev, struct bnxt_re_pd *pd,
 				struct bnxt_re_qp *qp, struct bnxt_re_ucontext *cntx,
-				struct bnxt_re_qp_req *ureq)
+				struct bnxt_re_qp_req *ureq,
+				bool fixed_que_attr)
 {
 	struct bnxt_qplib_qp *qplib_qp;
 	struct ib_umem *umem;
@@ -1193,7 +1203,7 @@ static int bnxt_re_init_user_qp(struct bnxt_re_dev *rdev, struct bnxt_re_pd *pd,
 	bytes = (qplib_qp->sq.max_wqe * qplib_qp->sq.wqe_size);
 	/* Consider mapping PSN search memory only for RC QPs. */
 	if (qplib_qp->type == CMDQ_CREATE_QP_TYPE_RC)
-		bytes += bnxt_re_get_psn_bytes(rdev, cntx, qplib_qp, ureq);
+		bytes += bnxt_re_get_psn_bytes(rdev, cntx, qplib_qp, ureq, fixed_que_attr);
 
 	bytes = PAGE_ALIGN(bytes);
 	umem = ib_umem_get(&rdev->ibdev, ureq->qpsva, bytes,
@@ -1647,7 +1657,9 @@ static int bnxt_re_init_qp_type(struct bnxt_re_dev *rdev,
 	return qptype;
 }
 
-static void bnxt_re_qp_calculate_msn_psn_size(struct bnxt_re_qp *qp)
+static void bnxt_re_qp_calculate_msn_psn_size(struct bnxt_re_qp *qp,
+					      bool fixed_que_attr,
+					      struct bnxt_re_qp_req *req)
 {
 	struct bnxt_qplib_qp *qplib_qp = &qp->qplib_qp;
 	struct bnxt_qplib_q *sq = &qplib_qp->sq;
@@ -1670,12 +1682,17 @@ static void bnxt_re_qp_calculate_msn_psn_size(struct bnxt_re_qp *qp)
 
 	/* Update msn tbl size */
 	if (qplib_qp->is_host_msn_tbl && qplib_qp->psn_sz) {
-		if (wqe_mode == BNXT_QPLIB_WQE_MODE_STATIC)
-			qplib_qp->msn_tbl_sz =
-				roundup_pow_of_two(bnxt_qplib_set_sq_size(sq, wqe_mode));
-		else
-			qplib_qp->msn_tbl_sz =
-				roundup_pow_of_two(bnxt_qplib_set_sq_size(sq, wqe_mode)) / 2;
+		if (!fixed_que_attr) {
+			if (wqe_mode == BNXT_QPLIB_WQE_MODE_STATIC)
+				qplib_qp->msn_tbl_sz =
+					roundup_pow_of_two(bnxt_qplib_set_sq_size(sq, wqe_mode));
+			else
+				qplib_qp->msn_tbl_sz =
+					roundup_pow_of_two(bnxt_qplib_set_sq_size(sq, wqe_mode))
+						/ 2;
+		} else {
+			qplib_qp->msn_tbl_sz = req->sq_npsn;
+		}
 		qplib_qp->msn = 0;
 	}
 }
@@ -1750,12 +1767,12 @@ static int bnxt_re_init_qp_attr(struct bnxt_re_qp *qp, struct bnxt_re_pd *pd,
 		bnxt_re_adjust_gsi_sq_attr(qp, init_attr, uctx);
 
 	if (uctx) { /* This will update DPI and qp_handle */
-		rc = bnxt_re_init_user_qp(rdev, pd, qp, uctx, ureq);
+		rc = bnxt_re_init_user_qp(rdev, pd, qp, uctx, ureq, fixed_que_attr);
 		if (rc)
 			return rc;
 	}
 
-	bnxt_re_qp_calculate_msn_psn_size(qp);
+	bnxt_re_qp_calculate_msn_psn_size(qp, fixed_que_attr, ureq);
 
 	rc = bnxt_re_setup_qp_hwqs(qp);
 	if (rc)
diff --git a/include/uapi/rdma/bnxt_re-abi.h b/include/uapi/rdma/bnxt_re-abi.h
index 40955eaba32e..db8400f2ce3b 100644
--- a/include/uapi/rdma/bnxt_re-abi.h
+++ b/include/uapi/rdma/bnxt_re-abi.h
@@ -135,6 +135,7 @@ struct bnxt_re_qp_req {
 	__aligned_u64 qp_handle;
 	__aligned_u64 comp_mask;
 	__u32 sq_slots;
+	__u32 sq_npsn;
 };
 
 struct bnxt_re_qp_resp {
-- 
2.51.2.636.ga99f379adf


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

* [PATCH rdma-next v6 5/9] RDMA/bnxt_re: Update hwq depth for app allocated QPs
  2026-05-18 15:37 [PATCH rdma-next v6 0/9] RDMA/bnxt_re: Support QP uapi extensions Sriharsha Basavapatna
                   ` (3 preceding siblings ...)
  2026-05-18 15:37 ` [PATCH rdma-next v6 4/9] RDMA/bnxt_re: Update msn table size " Sriharsha Basavapatna
@ 2026-05-18 15:37 ` Sriharsha Basavapatna
  2026-05-18 15:37 ` [PATCH rdma-next v6 6/9] RDMA/bnxt_re: Enhance dbr usecnt logic in doorbell uapis Sriharsha Basavapatna
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 17+ messages in thread
From: Sriharsha Basavapatna @ 2026-05-18 15:37 UTC (permalink / raw)
  To: leon, jgg
  Cc: linux-rdma, andrew.gospodarek, selvin.xavier,
	kalesh-anakkur.purayil, Sriharsha Basavapatna

The hwq depth shouldn't be computed using slots/round-up logic for
app allocated QPs, use the max_wqe value saved earlier.

Signed-off-by: Sriharsha Basavapatna <sriharsha.basavapatna@broadcom.com>
Reviewed-by: Selvin Xavier <selvin.xavier@broadcom.com>
---
 drivers/infiniband/hw/bnxt_re/ib_verbs.c | 23 ++++++++++++++++-------
 1 file changed, 16 insertions(+), 7 deletions(-)

diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.c b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
index ae32f86b9e9b..9fd85d81bcea 100644
--- a/drivers/infiniband/hw/bnxt_re/ib_verbs.c
+++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
@@ -1346,7 +1346,7 @@ static int bnxt_re_qp_alloc_init_xrrq(struct bnxt_re_qp *qp)
 	return rc;
 }
 
-static int bnxt_re_setup_qp_hwqs(struct bnxt_re_qp *qp)
+static int bnxt_re_setup_qp_hwqs(struct bnxt_re_qp *qp, bool fixed_que_attr)
 {
 	struct bnxt_qplib_res *res = &qp->rdev->qplib_res;
 	struct bnxt_qplib_qp *qplib_qp = &qp->qplib_qp;
@@ -1360,12 +1360,17 @@ static int bnxt_re_setup_qp_hwqs(struct bnxt_re_qp *qp)
 	hwq_attr.res = res;
 	hwq_attr.sginfo = &sq->sg_info;
 	hwq_attr.stride = bnxt_qplib_get_stride();
-	hwq_attr.depth = bnxt_qplib_get_depth(sq, wqe_mode, true);
 	hwq_attr.aux_stride = qplib_qp->psn_sz;
-	hwq_attr.aux_depth = (qplib_qp->psn_sz) ?
-		bnxt_qplib_set_sq_size(sq, wqe_mode) : 0;
-	if (qplib_qp->is_host_msn_tbl && qplib_qp->psn_sz)
+	if (!fixed_que_attr) {
+		hwq_attr.depth = bnxt_qplib_get_depth(sq, wqe_mode, true);
+		hwq_attr.aux_depth = (qplib_qp->psn_sz) ?
+				bnxt_qplib_set_sq_size(sq, wqe_mode) : 0;
+		if (qplib_qp->is_host_msn_tbl && qplib_qp->psn_sz)
+			hwq_attr.aux_depth = qplib_qp->msn_tbl_sz;
+	} else {
+		hwq_attr.depth = sq->max_wqe;
 		hwq_attr.aux_depth = qplib_qp->msn_tbl_sz;
+	}
 	hwq_attr.type = HWQ_TYPE_QUEUE;
 	rc = bnxt_qplib_alloc_init_hwq(&sq->hwq, &hwq_attr);
 	if (rc)
@@ -1376,6 +1381,9 @@ static int bnxt_re_setup_qp_hwqs(struct bnxt_re_qp *qp)
 		      CMDQ_CREATE_QP_SQ_LVL_SFT);
 	sq->hwq.pg_sz_lvl = pg_sz_lvl;
 
+	if (qplib_qp->srq)
+		goto done;
+
 	hwq_attr.res = res;
 	hwq_attr.sginfo = &rq->sg_info;
 	hwq_attr.stride = bnxt_qplib_get_stride();
@@ -1392,6 +1400,7 @@ static int bnxt_re_setup_qp_hwqs(struct bnxt_re_qp *qp)
 		      CMDQ_CREATE_QP_RQ_LVL_SFT);
 	rq->hwq.pg_sz_lvl = pg_sz_lvl;
 
+done:
 	if (qplib_qp->psn_sz) {
 		rc = bnxt_re_qp_alloc_init_xrrq(qp);
 		if (rc)
@@ -1460,7 +1469,7 @@ static struct bnxt_re_qp *bnxt_re_create_shadow_qp
 	qp->qplib_qp.rq_hdr_buf_size = BNXT_QPLIB_MAX_GRH_HDR_SIZE_IPV6;
 	qp->qplib_qp.dpi = &rdev->dpi_privileged;
 
-	rc = bnxt_re_setup_qp_hwqs(qp);
+	rc = bnxt_re_setup_qp_hwqs(qp, false);
 	if (rc)
 		goto fail;
 
@@ -1774,7 +1783,7 @@ static int bnxt_re_init_qp_attr(struct bnxt_re_qp *qp, struct bnxt_re_pd *pd,
 
 	bnxt_re_qp_calculate_msn_psn_size(qp, fixed_que_attr, ureq);
 
-	rc = bnxt_re_setup_qp_hwqs(qp);
+	rc = bnxt_re_setup_qp_hwqs(qp, fixed_que_attr);
 	if (rc)
 		goto free_umem;
 
-- 
2.51.2.636.ga99f379adf


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

* [PATCH rdma-next v6 6/9] RDMA/bnxt_re: Enhance dbr usecnt logic in doorbell uapis
  2026-05-18 15:37 [PATCH rdma-next v6 0/9] RDMA/bnxt_re: Support QP uapi extensions Sriharsha Basavapatna
                   ` (4 preceding siblings ...)
  2026-05-18 15:37 ` [PATCH rdma-next v6 5/9] RDMA/bnxt_re: Update hwq depth " Sriharsha Basavapatna
@ 2026-05-18 15:37 ` Sriharsha Basavapatna
  2026-05-18 15:37 ` [PATCH rdma-next v6 7/9] RDMA/bnxt_re: Enhance dpi lifecycle " Sriharsha Basavapatna
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 17+ messages in thread
From: Sriharsha Basavapatna @ 2026-05-18 15:37 UTC (permalink / raw)
  To: leon, jgg
  Cc: linux-rdma, andrew.gospodarek, selvin.xavier,
	kalesh-anakkur.purayil, Sriharsha Basavapatna

The current logic in the doorbell cleanup function is not
sufficient for a change in a subsequent patch, that fails
doorbell remove operation in some conditions. The cleanup
should facilitate freeing of the dbr object when the caller
may not retry the teardown operation (implicit teardown:
process-exit/driver-removal).

Extend this counter to use kref mechanism so that the dbr
object gets freed (via kref callback) when there are no more
references to it, rather than directly freeing it in the
cleanup uapi.

Signed-off-by: Sriharsha Basavapatna <sriharsha.basavapatna@broadcom.com>
Reviewed-by: Selvin Xavier <selvin.xavier@broadcom.com>
---
 drivers/infiniband/hw/bnxt_re/ib_verbs.h |  3 ++-
 drivers/infiniband/hw/bnxt_re/uapi.c     | 16 +++++++++++++---
 2 files changed, 15 insertions(+), 4 deletions(-)

diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.h b/drivers/infiniband/hw/bnxt_re/ib_verbs.h
index 08f71a94d55d..13dac48ed453 100644
--- a/drivers/infiniband/hw/bnxt_re/ib_verbs.h
+++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.h
@@ -167,7 +167,7 @@ struct bnxt_re_dbr_obj {
 	struct bnxt_re_dev *rdev;
 	struct bnxt_qplib_dpi dpi;
 	struct bnxt_re_user_mmap_entry *entry;
-	atomic_t usecnt; /* QPs using this dbr */
+	struct kref usecnt; /* 1 (uobject) + n (QPs using this dbr) */
 };
 
 struct bnxt_re_flow {
@@ -308,4 +308,5 @@ void bnxt_re_unlock_cqs(struct bnxt_re_qp *qp, unsigned long flags);
 struct bnxt_re_user_mmap_entry*
 bnxt_re_mmap_entry_insert(struct bnxt_re_ucontext *uctx, u64 mem_offset,
 			  enum bnxt_re_mmap_flag mmap_flag, u64 *offset);
+void bnxt_re_dbr_kref_release(struct kref *ref);
 #endif /* __BNXT_RE_IB_VERBS_H__ */
diff --git a/drivers/infiniband/hw/bnxt_re/uapi.c b/drivers/infiniband/hw/bnxt_re/uapi.c
index 3eaee7101615..b8fc8bfba2ad 100644
--- a/drivers/infiniband/hw/bnxt_re/uapi.c
+++ b/drivers/infiniband/hw/bnxt_re/uapi.c
@@ -369,6 +369,7 @@ static int UVERBS_HANDLER(BNXT_RE_METHOD_DBR_ALLOC)(struct uverbs_attr_bundle *a
 	}
 
 	obj->rdev = rdev;
+	kref_init(&obj->usecnt);
 	uobj->object = obj;
 	uverbs_finalize_uobj_create(attrs, BNXT_RE_ALLOC_DBR_HANDLE);
 
@@ -391,15 +392,24 @@ static int UVERBS_HANDLER(BNXT_RE_METHOD_DBR_ALLOC)(struct uverbs_attr_bundle *a
 	return ret;
 }
 
+void bnxt_re_dbr_kref_release(struct kref *ref)
+{
+	struct bnxt_re_dbr_obj *obj =
+		container_of(ref, struct bnxt_re_dbr_obj, usecnt);
+	struct bnxt_re_dev *rdev = obj->rdev;
+
+	rdma_user_mmap_entry_remove(&obj->entry->rdma_entry);
+	bnxt_qplib_free_uc_dpi(&rdev->qplib_res, &obj->dpi);
+	kfree(obj);
+}
+
 static int bnxt_re_dbr_cleanup(struct ib_uobject *uobject,
 			       enum rdma_remove_reason why,
 			       struct uverbs_attr_bundle *attrs)
 {
 	struct bnxt_re_dbr_obj *obj = uobject->object;
-	struct bnxt_re_dev *rdev = obj->rdev;
 
-	rdma_user_mmap_entry_remove(&obj->entry->rdma_entry);
-	bnxt_qplib_free_uc_dpi(&rdev->qplib_res, &obj->dpi);
+	kref_put(&obj->usecnt, bnxt_re_dbr_kref_release);
 	return 0;
 }
 
-- 
2.51.2.636.ga99f379adf


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

* [PATCH rdma-next v6 7/9] RDMA/bnxt_re: Enhance dpi lifecycle logic in doorbell uapis
  2026-05-18 15:37 [PATCH rdma-next v6 0/9] RDMA/bnxt_re: Support QP uapi extensions Sriharsha Basavapatna
                   ` (5 preceding siblings ...)
  2026-05-18 15:37 ` [PATCH rdma-next v6 6/9] RDMA/bnxt_re: Enhance dbr usecnt logic in doorbell uapis Sriharsha Basavapatna
@ 2026-05-18 15:37 ` Sriharsha Basavapatna
  2026-05-19  9:27   ` Sriharsha Basavapatna
  2026-05-18 15:37 ` [PATCH rdma-next v6 8/9] RDMA/bnxt_re: Support doorbells for app allocated QPs Sriharsha Basavapatna
  2026-05-18 15:37 ` [PATCH rdma-next v6 9/9] RDMA/bnxt_re: Enable " Sriharsha Basavapatna
  8 siblings, 1 reply; 17+ messages in thread
From: Sriharsha Basavapatna @ 2026-05-18 15:37 UTC (permalink / raw)
  To: leon, jgg
  Cc: linux-rdma, andrew.gospodarek, selvin.xavier,
	kalesh-anakkur.purayil, Sriharsha Basavapatna

If the DPI is freed when the dbr object is freed, but if the
process has not unmapped the page yet, then the DPI slot could
get reallocated to another process while the original process
still has it mapped. To prevent this, save the DPI info in the
mmap entry during dbr allocation and free the DPI slot from
bnxt_re_mmap_free(), which enures that there are no references
to it.

This change is needed to support doorbell allocation to QPs
in the next patch.

Signed-off-by: Sriharsha Basavapatna <sriharsha.basavapatna@broadcom.com>
Reviewed-by: Selvin Xavier <selvin.xavier@broadcom.com>
---
 drivers/infiniband/hw/bnxt_re/ib_verbs.c |  4 ++++
 drivers/infiniband/hw/bnxt_re/ib_verbs.h |  1 +
 drivers/infiniband/hw/bnxt_re/uapi.c     | 12 ++++++++++--
 3 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.c b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
index 9fd85d81bcea..b8e46feafee7 100644
--- a/drivers/infiniband/hw/bnxt_re/ib_verbs.c
+++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
@@ -4943,6 +4943,10 @@ void bnxt_re_mmap_free(struct rdma_user_mmap_entry *rdma_entry)
 	bnxt_entry = container_of(rdma_entry, struct bnxt_re_user_mmap_entry,
 				  rdma_entry);
 
+	if (bnxt_entry->mmap_flag == BNXT_RE_MMAP_UC_DB && bnxt_entry->uctx)
+		bnxt_qplib_free_uc_dpi(&bnxt_entry->uctx->rdev->qplib_res,
+				       &bnxt_entry->dpi);
+
 	kfree(bnxt_entry);
 }
 
diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.h b/drivers/infiniband/hw/bnxt_re/ib_verbs.h
index 13dac48ed453..1caef68a5c38 100644
--- a/drivers/infiniband/hw/bnxt_re/ib_verbs.h
+++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.h
@@ -161,6 +161,7 @@ struct bnxt_re_user_mmap_entry {
 	struct bnxt_re_ucontext *uctx;
 	u64 mem_offset;
 	u8 mmap_flag;
+	struct bnxt_qplib_dpi dpi;
 };
 
 struct bnxt_re_dbr_obj {
diff --git a/drivers/infiniband/hw/bnxt_re/uapi.c b/drivers/infiniband/hw/bnxt_re/uapi.c
index b8fc8bfba2ad..866df9206f5a 100644
--- a/drivers/infiniband/hw/bnxt_re/uapi.c
+++ b/drivers/infiniband/hw/bnxt_re/uapi.c
@@ -368,6 +368,12 @@ static int UVERBS_HANDLER(BNXT_RE_METHOD_DBR_ALLOC)(struct uverbs_attr_bundle *a
 		goto free_dpi;
 	}
 
+	/* Save DPI info to the mmap entry so that bnxt_re_mmap_free()
+	 * can free the DPI slot only after the last reference to the
+	 * mmap entry is released.
+	 */
+	obj->entry->dpi = *dpi;
+
 	obj->rdev = rdev;
 	kref_init(&obj->usecnt);
 	uobj->object = obj;
@@ -396,10 +402,12 @@ void bnxt_re_dbr_kref_release(struct kref *ref)
 {
 	struct bnxt_re_dbr_obj *obj =
 		container_of(ref, struct bnxt_re_dbr_obj, usecnt);
-	struct bnxt_re_dev *rdev = obj->rdev;
 
+	/* Drop the driver's reference to the mmap entry (_remove()).
+	 * The DPI slot gets freed from bnxt_re_mmap_free() only
+	 * when there's no VMA mapping reference to it.
+	 */
 	rdma_user_mmap_entry_remove(&obj->entry->rdma_entry);
-	bnxt_qplib_free_uc_dpi(&rdev->qplib_res, &obj->dpi);
 	kfree(obj);
 }
 
-- 
2.51.2.636.ga99f379adf


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

* [PATCH rdma-next v6 8/9] RDMA/bnxt_re: Support doorbells for app allocated QPs
  2026-05-18 15:37 [PATCH rdma-next v6 0/9] RDMA/bnxt_re: Support QP uapi extensions Sriharsha Basavapatna
                   ` (6 preceding siblings ...)
  2026-05-18 15:37 ` [PATCH rdma-next v6 7/9] RDMA/bnxt_re: Enhance dpi lifecycle " Sriharsha Basavapatna
@ 2026-05-18 15:37 ` Sriharsha Basavapatna
  2026-05-18 15:37 ` [PATCH rdma-next v6 9/9] RDMA/bnxt_re: Enable " Sriharsha Basavapatna
  8 siblings, 0 replies; 17+ messages in thread
From: Sriharsha Basavapatna @ 2026-05-18 15:37 UTC (permalink / raw)
  To: leon, jgg
  Cc: linux-rdma, andrew.gospodarek, selvin.xavier,
	kalesh-anakkur.purayil, Sriharsha Basavapatna

App allocated QPs can use a separate doorbell for each QP.
This doorbell region can be passed through a new driver specific
DBR_HANDLE attribute, during QP creation. When this attribute
is set, associate the QP with the given doorbell region.

While the QP holds a reference to the dbr, the dbr itself
cannot be destroyed and is rejected with EBUSY error.

Signed-off-by: Sriharsha Basavapatna <sriharsha.basavapatna@broadcom.com>
Reviewed-by: Selvin Xavier <selvin.xavier@broadcom.com>
---
 drivers/infiniband/hw/bnxt_re/ib_verbs.c | 35 ++++++++++++++++++++----
 drivers/infiniband/hw/bnxt_re/ib_verbs.h |  1 +
 drivers/infiniband/hw/bnxt_re/uapi.c     | 24 ++++++++++++++++
 include/uapi/rdma/bnxt_re-abi.h          |  4 +++
 4 files changed, 59 insertions(+), 5 deletions(-)

diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.c b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
index b8e46feafee7..ba8f7f94131b 100644
--- a/drivers/infiniband/hw/bnxt_re/ib_verbs.c
+++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
@@ -1024,6 +1024,9 @@ int bnxt_re_destroy_qp(struct ib_qp *ib_qp, struct ib_udata *udata)
 	if (rc)
 		ibdev_err(&rdev->ibdev, "Failed to destroy HW QP");
 
+	if (qp->dbr_obj)
+		kref_put(&qp->dbr_obj->usecnt, bnxt_re_dbr_kref_release);
+
 	if (rdma_is_kernel_res(&qp->ib_qp.res)) {
 		flags = bnxt_re_lock_cqs(qp);
 		bnxt_qplib_clean_qp(&qp->qplib_qp);
@@ -1191,7 +1194,8 @@ static int bnxt_re_get_psn_bytes(struct bnxt_re_dev *rdev,
 static int bnxt_re_init_user_qp(struct bnxt_re_dev *rdev, struct bnxt_re_pd *pd,
 				struct bnxt_re_qp *qp, struct bnxt_re_ucontext *cntx,
 				struct bnxt_re_qp_req *ureq,
-				bool fixed_que_attr)
+				bool fixed_que_attr,
+				struct bnxt_re_dbr_obj *dbr_obj)
 {
 	struct bnxt_qplib_qp *qplib_qp;
 	struct ib_umem *umem;
@@ -1234,8 +1238,11 @@ static int bnxt_re_init_user_qp(struct bnxt_re_dev *rdev, struct bnxt_re_pd *pd,
 		goto rqfail;
 
 done:
+	if (dbr_obj)
+		qplib_qp->dpi = &dbr_obj->dpi;
+	else
+		qplib_qp->dpi = &cntx->dpi;
 	qplib_qp->qp_handle = ureq->qp_handle;
-	qplib_qp->dpi = &cntx->dpi;
 	qplib_qp->is_user = true;
 	return 0;
 
@@ -1709,7 +1716,8 @@ static void bnxt_re_qp_calculate_msn_psn_size(struct bnxt_re_qp *qp,
 static int bnxt_re_init_qp_attr(struct bnxt_re_qp *qp, struct bnxt_re_pd *pd,
 				struct ib_qp_init_attr *init_attr,
 				struct bnxt_re_ucontext *uctx,
-				struct bnxt_re_qp_req *ureq)
+				struct bnxt_re_qp_req *ureq,
+				struct bnxt_re_dbr_obj *dbr_obj)
 {
 	struct bnxt_qplib_dev_attr *dev_attr;
 	struct bnxt_qplib_qp *qplqp;
@@ -1776,7 +1784,8 @@ static int bnxt_re_init_qp_attr(struct bnxt_re_qp *qp, struct bnxt_re_pd *pd,
 		bnxt_re_adjust_gsi_sq_attr(qp, init_attr, uctx);
 
 	if (uctx) { /* This will update DPI and qp_handle */
-		rc = bnxt_re_init_user_qp(rdev, pd, qp, uctx, ureq, fixed_que_attr);
+		rc = bnxt_re_init_user_qp(rdev, pd, qp, uctx, ureq, fixed_que_attr,
+					  dbr_obj);
 		if (rc)
 			return rc;
 	}
@@ -1912,7 +1921,9 @@ static int bnxt_re_add_unique_gid(struct bnxt_re_dev *rdev)
 int bnxt_re_create_qp(struct ib_qp *ib_qp, struct ib_qp_init_attr *qp_init_attr,
 		      struct ib_udata *udata)
 {
+	struct bnxt_re_dbr_obj *dbr_obj = NULL;
 	struct bnxt_qplib_dev_attr *dev_attr;
+	struct uverbs_attr_bundle *attrs;
 	struct bnxt_re_ucontext *uctx;
 	struct bnxt_re_qp_req ureq;
 	struct bnxt_re_dev *rdev;
@@ -1933,6 +1944,17 @@ int bnxt_re_create_qp(struct ib_qp *ib_qp, struct ib_qp_init_attr *qp_init_attr,
 		rc = ib_copy_validate_udata_in_cm(udata, ureq, qp_handle, 0);
 		if (rc)
 			return rc;
+
+		attrs = rdma_udata_to_uverbs_attr_bundle(udata);
+		if (uverbs_attr_is_valid(attrs,
+					 BNXT_RE_CREATE_QP_ATTR_DBR_HANDLE)) {
+			dbr_obj = uverbs_attr_get_obj(attrs,
+						      BNXT_RE_CREATE_QP_ATTR_DBR_HANDLE);
+			if (IS_ERR(dbr_obj))
+				return PTR_ERR(dbr_obj);
+			kref_get(&dbr_obj->usecnt);
+			qp->dbr_obj = dbr_obj;
+		}
 	}
 
 	rc = bnxt_re_test_qp_limits(rdev, qp_init_attr, dev_attr);
@@ -1942,7 +1964,8 @@ int bnxt_re_create_qp(struct ib_qp *ib_qp, struct ib_qp_init_attr *qp_init_attr,
 	}
 
 	qp->rdev = rdev;
-	rc = bnxt_re_init_qp_attr(qp, pd, qp_init_attr, uctx, &ureq);
+	rc = bnxt_re_init_qp_attr(qp, pd, qp_init_attr, uctx, &ureq,
+				  dbr_obj);
 	if (rc)
 		goto fail;
 
@@ -2012,6 +2035,8 @@ int bnxt_re_create_qp(struct ib_qp *ib_qp, struct ib_qp_init_attr *qp_init_attr,
 	bnxt_qplib_free_qp_res(&rdev->qplib_res, &qp->qplib_qp);
 	bnxt_re_qp_free_umem(qp);
 fail:
+	if (dbr_obj)
+		kref_put(&dbr_obj->usecnt, bnxt_re_dbr_kref_release);
 	return rc;
 }
 
diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.h b/drivers/infiniband/hw/bnxt_re/ib_verbs.h
index 1caef68a5c38..89cd5d946f30 100644
--- a/drivers/infiniband/hw/bnxt_re/ib_verbs.h
+++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.h
@@ -96,6 +96,7 @@ struct bnxt_re_qp {
 	struct bnxt_re_cq	*scq;
 	struct bnxt_re_cq	*rcq;
 	struct dentry		*dentry;
+	struct bnxt_re_dbr_obj *dbr_obj; /* doorbell region */
 };
 
 struct bnxt_re_cq {
diff --git a/drivers/infiniband/hw/bnxt_re/uapi.c b/drivers/infiniband/hw/bnxt_re/uapi.c
index 866df9206f5a..b9a89c419746 100644
--- a/drivers/infiniband/hw/bnxt_re/uapi.c
+++ b/drivers/infiniband/hw/bnxt_re/uapi.c
@@ -417,6 +417,15 @@ static int bnxt_re_dbr_cleanup(struct ib_uobject *uobject,
 {
 	struct bnxt_re_dbr_obj *obj = uobject->object;
 
+	/* If it is being destroyed explicitly while QPs still hold a
+	 * reference (> 1), reject it with EBUSY. If no QP references
+	 * or implicit teardown (process exit, driver removal), drop
+	 * the uobject reference unconditionally. The object gets freed
+	 * (bnxt_re_dbr_kref_release) when the usecnt goes to zero.
+	 */
+	if (why == RDMA_REMOVE_DESTROY && kref_read(&obj->usecnt) > 1)
+		return -EBUSY;
+
 	kref_put(&obj->usecnt, bnxt_re_dbr_kref_release);
 	return 0;
 }
@@ -477,11 +486,26 @@ DECLARE_UVERBS_NAMED_METHOD(BNXT_RE_METHOD_GET_DEFAULT_DBR,
 DECLARE_UVERBS_GLOBAL_METHODS(BNXT_RE_OBJECT_DEFAULT_DBR,
 			      &UVERBS_METHOD(BNXT_RE_METHOD_GET_DEFAULT_DBR));
 
+ADD_UVERBS_ATTRIBUTES_SIMPLE(
+	bnxt_re_qp_create,
+	UVERBS_OBJECT_QP,
+	UVERBS_METHOD_QP_CREATE,
+	UVERBS_ATTR_IDR(BNXT_RE_CREATE_QP_ATTR_DBR_HANDLE,
+			BNXT_RE_OBJECT_DBR,
+			UVERBS_ACCESS_READ,
+			UA_OPTIONAL));
+
+const struct uapi_definition bnxt_re_create_qp_defs[] = {
+	UAPI_DEF_CHAIN_OBJ_TREE(UVERBS_OBJECT_QP, &bnxt_re_qp_create),
+	{},
+};
+
 const struct uapi_definition bnxt_re_uapi_defs[] = {
 	UAPI_DEF_CHAIN_OBJ_TREE_NAMED(BNXT_RE_OBJECT_ALLOC_PAGE),
 	UAPI_DEF_CHAIN_OBJ_TREE_NAMED(BNXT_RE_OBJECT_NOTIFY_DRV),
 	UAPI_DEF_CHAIN_OBJ_TREE_NAMED(BNXT_RE_OBJECT_GET_TOGGLE_MEM),
 	UAPI_DEF_CHAIN_OBJ_TREE_NAMED(BNXT_RE_OBJECT_DBR),
 	UAPI_DEF_CHAIN_OBJ_TREE_NAMED(BNXT_RE_OBJECT_DEFAULT_DBR),
+	UAPI_DEF_CHAIN(bnxt_re_create_qp_defs),
 	{}
 };
diff --git a/include/uapi/rdma/bnxt_re-abi.h b/include/uapi/rdma/bnxt_re-abi.h
index db8400f2ce3b..4da8cda337dc 100644
--- a/include/uapi/rdma/bnxt_re-abi.h
+++ b/include/uapi/rdma/bnxt_re-abi.h
@@ -138,6 +138,10 @@ struct bnxt_re_qp_req {
 	__u32 sq_npsn;
 };
 
+enum bnxt_re_create_qp_attrs {
+	BNXT_RE_CREATE_QP_ATTR_DBR_HANDLE = UVERBS_ID_DRIVER_NS_WITH_UHW,
+};
+
 struct bnxt_re_qp_resp {
 	__u32 qpid;
 	__u32 rsvd;
-- 
2.51.2.636.ga99f379adf


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

* [PATCH rdma-next v6 9/9] RDMA/bnxt_re: Enable app allocated QPs
  2026-05-18 15:37 [PATCH rdma-next v6 0/9] RDMA/bnxt_re: Support QP uapi extensions Sriharsha Basavapatna
                   ` (7 preceding siblings ...)
  2026-05-18 15:37 ` [PATCH rdma-next v6 8/9] RDMA/bnxt_re: Support doorbells for app allocated QPs Sriharsha Basavapatna
@ 2026-05-18 15:37 ` Sriharsha Basavapatna
  8 siblings, 0 replies; 17+ messages in thread
From: Sriharsha Basavapatna @ 2026-05-18 15:37 UTC (permalink / raw)
  To: leon, jgg
  Cc: linux-rdma, andrew.gospodarek, selvin.xavier,
	kalesh-anakkur.purayil, Sriharsha Basavapatna

The driver supports a new comp_mask: REQ_MASK_FIXED_QUE_ATTR.
The application sets this comp_mask bit in the CREATE_QP ureq
to indicate direct control of the QP. The driver goes through
the required processing for app allocated QPs (previous patches).
Only variable WQE mode is supported for these QPs.

This patch removes an unused comp_mask:
	BNXT_RE_QP_REQ_MASK_VAR_WQE_SQ_SLOTS

Signed-off-by: Sriharsha Basavapatna <sriharsha.basavapatna@broadcom.com>
Reviewed-by: Selvin Xavier <selvin.xavier@broadcom.com>
---
 drivers/infiniband/hw/bnxt_re/ib_verbs.c | 19 +++++++++++++++----
 include/uapi/rdma/bnxt_re-abi.h          |  2 +-
 2 files changed, 16 insertions(+), 5 deletions(-)

diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.c b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
index ba8f7f94131b..1d0ca766a174 100644
--- a/drivers/infiniband/hw/bnxt_re/ib_verbs.c
+++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
@@ -1717,11 +1717,11 @@ static int bnxt_re_init_qp_attr(struct bnxt_re_qp *qp, struct bnxt_re_pd *pd,
 				struct ib_qp_init_attr *init_attr,
 				struct bnxt_re_ucontext *uctx,
 				struct bnxt_re_qp_req *ureq,
-				struct bnxt_re_dbr_obj *dbr_obj)
+				struct bnxt_re_dbr_obj *dbr_obj,
+				bool fixed_que_attr)
 {
 	struct bnxt_qplib_dev_attr *dev_attr;
 	struct bnxt_qplib_qp *qplqp;
-	bool fixed_que_attr = false;
 	struct bnxt_re_dev *rdev;
 	struct bnxt_re_cq *cq;
 	int rc = 0, qptype;
@@ -1741,6 +1741,13 @@ 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 (fixed_que_attr) {
+		if (qplqp->wqe_mode != BNXT_QPLIB_WQE_MODE_VARIABLE)
+			return -EOPNOTSUPP;
+		if (!ureq->sq_npsn ||
+		    ureq->sq_npsn > roundup_pow_of_two(ureq->sq_slots / 2))
+			return -EINVAL;
+	}
 	qplqp->dev_cap_flags = dev_attr->dev_cap_flags;
 	qplqp->cctx = rdev->chip_ctx;
 	if (init_attr->qp_type == IB_QPT_RC) {
@@ -1925,6 +1932,7 @@ int bnxt_re_create_qp(struct ib_qp *ib_qp, struct ib_qp_init_attr *qp_init_attr,
 	struct bnxt_qplib_dev_attr *dev_attr;
 	struct uverbs_attr_bundle *attrs;
 	struct bnxt_re_ucontext *uctx;
+	bool fixed_que_attr = false;
 	struct bnxt_re_qp_req ureq;
 	struct bnxt_re_dev *rdev;
 	struct bnxt_re_pd *pd;
@@ -1941,7 +1949,8 @@ int bnxt_re_create_qp(struct ib_qp *ib_qp, struct ib_qp_init_attr *qp_init_attr,
 
 	uctx = rdma_udata_to_drv_context(udata, struct bnxt_re_ucontext, ib_uctx);
 	if (udata) {
-		rc = ib_copy_validate_udata_in_cm(udata, ureq, qp_handle, 0);
+		rc = ib_copy_validate_udata_in_cm(udata, ureq, qp_handle,
+						  BNXT_RE_QP_REQ_MASK_FIXED_QUE_ATTR);
 		if (rc)
 			return rc;
 
@@ -1955,6 +1964,8 @@ int bnxt_re_create_qp(struct ib_qp *ib_qp, struct ib_qp_init_attr *qp_init_attr,
 			kref_get(&dbr_obj->usecnt);
 			qp->dbr_obj = dbr_obj;
 		}
+		if (ureq.comp_mask & BNXT_RE_QP_REQ_MASK_FIXED_QUE_ATTR)
+			fixed_que_attr = true;
 	}
 
 	rc = bnxt_re_test_qp_limits(rdev, qp_init_attr, dev_attr);
@@ -1965,7 +1976,7 @@ int bnxt_re_create_qp(struct ib_qp *ib_qp, struct ib_qp_init_attr *qp_init_attr,
 
 	qp->rdev = rdev;
 	rc = bnxt_re_init_qp_attr(qp, pd, qp_init_attr, uctx, &ureq,
-				  dbr_obj);
+				  dbr_obj, fixed_que_attr);
 	if (rc)
 		goto fail;
 
diff --git a/include/uapi/rdma/bnxt_re-abi.h b/include/uapi/rdma/bnxt_re-abi.h
index 4da8cda337dc..a4599d7b736a 100644
--- a/include/uapi/rdma/bnxt_re-abi.h
+++ b/include/uapi/rdma/bnxt_re-abi.h
@@ -126,7 +126,7 @@ struct bnxt_re_resize_cq_req {
 };
 
 enum bnxt_re_qp_mask {
-	BNXT_RE_QP_REQ_MASK_VAR_WQE_SQ_SLOTS = 0x1,
+	BNXT_RE_QP_REQ_MASK_FIXED_QUE_ATTR = 0x1,
 };
 
 struct bnxt_re_qp_req {
-- 
2.51.2.636.ga99f379adf


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

* Re: [PATCH rdma-next v6 7/9] RDMA/bnxt_re: Enhance dpi lifecycle logic in doorbell uapis
  2026-05-18 15:37 ` [PATCH rdma-next v6 7/9] RDMA/bnxt_re: Enhance dpi lifecycle " Sriharsha Basavapatna
@ 2026-05-19  9:27   ` Sriharsha Basavapatna
  2026-05-19 12:46     ` Jason Gunthorpe
  0 siblings, 1 reply; 17+ messages in thread
From: Sriharsha Basavapatna @ 2026-05-19  9:27 UTC (permalink / raw)
  To: leon, jgg
  Cc: linux-rdma, andrew.gospodarek, selvin.xavier,
	kalesh-anakkur.purayil, Sriharsha Basavapatna

[-- Attachment #1: Type: text/plain, Size: 4639 bytes --]

On Mon, May 18, 2026 at 9:17 PM Sriharsha Basavapatna
<sriharsha.basavapatna@broadcom.com> wrote:
>
> If the DPI is freed when the dbr object is freed, but if the
> process has not unmapped the page yet, then the DPI slot could
> get reallocated to another process while the original process
> still has it mapped. To prevent this, save the DPI info in the
> mmap entry during dbr allocation and free the DPI slot from
> bnxt_re_mmap_free(), which enures that there are no references
> to it.
>
> This change is needed to support doorbell allocation to QPs
> in the next patch.
>
> Signed-off-by: Sriharsha Basavapatna <sriharsha.basavapatna@broadcom.com>
> Reviewed-by: Selvin Xavier <selvin.xavier@broadcom.com>
> ---
>  drivers/infiniband/hw/bnxt_re/ib_verbs.c |  4 ++++
>  drivers/infiniband/hw/bnxt_re/ib_verbs.h |  1 +
>  drivers/infiniband/hw/bnxt_re/uapi.c     | 12 ++++++++++--
>  3 files changed, 15 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.c b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
> index 9fd85d81bcea..b8e46feafee7 100644
> --- a/drivers/infiniband/hw/bnxt_re/ib_verbs.c
> +++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
> @@ -4943,6 +4943,10 @@ void bnxt_re_mmap_free(struct rdma_user_mmap_entry *rdma_entry)
>         bnxt_entry = container_of(rdma_entry, struct bnxt_re_user_mmap_entry,
>                                   rdma_entry);
>
> +       if (bnxt_entry->mmap_flag == BNXT_RE_MMAP_UC_DB && bnxt_entry->uctx)
> +               bnxt_qplib_free_uc_dpi(&bnxt_entry->uctx->rdev->qplib_res,
> +                                      &bnxt_entry->dpi);
> +
>         kfree(bnxt_entry);
>  }
There's a sashiko warning on this change:

"Also, does this introduce a use-after-free during device hot-unplug?
During hot-unplug, the RDMA core tears down the ib_ucontext (which
embeds bnxt_re_ucontext) synchronously. However, active VMAs outlive
the ucontext because hot-unplug only zaps the PTEs without closing the
VMAs. When the process later exits or manually unmaps the memory,
bnxt_re_mmap_free() is triggered. Will dereferencing
bnxt_entry->uctx->rdev->qplib_res result in a use-after-free since the
uctx has already been freed?"

But reviewing the uverbs code, it does look like VMA mappings are
removed during hot-unplug. Also, ib_ucontext seems valid for the
driver to access during this process because dealloc_ucontext() is the
last step in this sequence (called after
uverbs_user_mmap_disassociate()).

ufile_destroy_ucontext(reason == RDMA_REMOVE_DRIVER_REMOVE) -->
uverbs_user_mmap_disassociate() --> rdma_user_mmap_entry_put() -->
rdma_user_mmap_entry_free() --> ucontext->device->ops.mmap_free()

Let me know if I'm missing something here.

Thanks,
-Harsha
>
> diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.h b/drivers/infiniband/hw/bnxt_re/ib_verbs.h
> index 13dac48ed453..1caef68a5c38 100644
> --- a/drivers/infiniband/hw/bnxt_re/ib_verbs.h
> +++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.h
> @@ -161,6 +161,7 @@ struct bnxt_re_user_mmap_entry {
>         struct bnxt_re_ucontext *uctx;
>         u64 mem_offset;
>         u8 mmap_flag;
> +       struct bnxt_qplib_dpi dpi;
>  };
>
>  struct bnxt_re_dbr_obj {
> diff --git a/drivers/infiniband/hw/bnxt_re/uapi.c b/drivers/infiniband/hw/bnxt_re/uapi.c
> index b8fc8bfba2ad..866df9206f5a 100644
> --- a/drivers/infiniband/hw/bnxt_re/uapi.c
> +++ b/drivers/infiniband/hw/bnxt_re/uapi.c
> @@ -368,6 +368,12 @@ static int UVERBS_HANDLER(BNXT_RE_METHOD_DBR_ALLOC)(struct uverbs_attr_bundle *a
>                 goto free_dpi;
>         }
>
> +       /* Save DPI info to the mmap entry so that bnxt_re_mmap_free()
> +        * can free the DPI slot only after the last reference to the
> +        * mmap entry is released.
> +        */
> +       obj->entry->dpi = *dpi;
> +
>         obj->rdev = rdev;
>         kref_init(&obj->usecnt);
>         uobj->object = obj;
> @@ -396,10 +402,12 @@ void bnxt_re_dbr_kref_release(struct kref *ref)
>  {
>         struct bnxt_re_dbr_obj *obj =
>                 container_of(ref, struct bnxt_re_dbr_obj, usecnt);
> -       struct bnxt_re_dev *rdev = obj->rdev;
>
> +       /* Drop the driver's reference to the mmap entry (_remove()).
> +        * The DPI slot gets freed from bnxt_re_mmap_free() only
> +        * when there's no VMA mapping reference to it.
> +        */
>         rdma_user_mmap_entry_remove(&obj->entry->rdma_entry);
> -       bnxt_qplib_free_uc_dpi(&rdev->qplib_res, &obj->dpi);
>         kfree(obj);
>  }
>
> --
> 2.51.2.636.ga99f379adf
>

[-- Attachment #2: S/MIME Cryptographic Signature --]
[-- Type: application/pkcs7-signature, Size: 5505 bytes --]

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

* Re: [PATCH rdma-next v6 7/9] RDMA/bnxt_re: Enhance dpi lifecycle logic in doorbell uapis
  2026-05-19  9:27   ` Sriharsha Basavapatna
@ 2026-05-19 12:46     ` Jason Gunthorpe
  2026-05-19 13:20       ` Sriharsha Basavapatna
  0 siblings, 1 reply; 17+ messages in thread
From: Jason Gunthorpe @ 2026-05-19 12:46 UTC (permalink / raw)
  To: Sriharsha Basavapatna
  Cc: leon, linux-rdma, andrew.gospodarek, selvin.xavier,
	kalesh-anakkur.purayil

On Tue, May 19, 2026 at 02:57:16PM +0530, Sriharsha Basavapatna wrote:
> On Mon, May 18, 2026 at 9:17 PM Sriharsha Basavapatna
> <sriharsha.basavapatna@broadcom.com> wrote:
> >
> > If the DPI is freed when the dbr object is freed, but if the
> > process has not unmapped the page yet, then the DPI slot could
> > get reallocated to another process while the original process
> > still has it mapped. To prevent this, save the DPI info in the
> > mmap entry during dbr allocation and free the DPI slot from
> > bnxt_re_mmap_free(), which enures that there are no references
> > to it.
> >
> > This change is needed to support doorbell allocation to QPs
> > in the next patch.
> >
> > Signed-off-by: Sriharsha Basavapatna <sriharsha.basavapatna@broadcom.com>
> > Reviewed-by: Selvin Xavier <selvin.xavier@broadcom.com>
> > ---
> >  drivers/infiniband/hw/bnxt_re/ib_verbs.c |  4 ++++
> >  drivers/infiniband/hw/bnxt_re/ib_verbs.h |  1 +
> >  drivers/infiniband/hw/bnxt_re/uapi.c     | 12 ++++++++++--
> >  3 files changed, 15 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.c b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
> > index 9fd85d81bcea..b8e46feafee7 100644
> > --- a/drivers/infiniband/hw/bnxt_re/ib_verbs.c
> > +++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
> > @@ -4943,6 +4943,10 @@ void bnxt_re_mmap_free(struct rdma_user_mmap_entry *rdma_entry)
> >         bnxt_entry = container_of(rdma_entry, struct bnxt_re_user_mmap_entry,
> >                                   rdma_entry);
> >
> > +       if (bnxt_entry->mmap_flag == BNXT_RE_MMAP_UC_DB && bnxt_entry->uctx)
> > +               bnxt_qplib_free_uc_dpi(&bnxt_entry->uctx->rdev->qplib_res,
> > +                                      &bnxt_entry->dpi);
> > +
> >         kfree(bnxt_entry);
> >  }
> There's a sashiko warning on this change:
> 
> "Also, does this introduce a use-after-free during device hot-unplug?
> During hot-unplug, the RDMA core tears down the ib_ucontext (which
> embeds bnxt_re_ucontext) synchronously. However, active VMAs outlive
> the ucontext because hot-unplug only zaps the PTEs without closing the
> VMAs. When the process later exits or manually unmaps the memory,
> bnxt_re_mmap_free() is triggered. Will dereferencing
> bnxt_entry->uctx->rdev->qplib_res result in a use-after-free since the
> uctx has already been freed?"

Hmm! That is a pretty reasonable assumption..

> ufile_destroy_ucontext(reason == RDMA_REMOVE_DRIVER_REMOVE) -->
> uverbs_user_mmap_disassociate() --> rdma_user_mmap_entry_put() -->
> rdma_user_mmap_entry_free() --> ucontext->device->ops.mmap_free()

Yes, that's right. The disassociate removes the references from all
the VMAs so it should always eventually call free.

However, it would be best if we didn't have this code in the free
callback at all, ideally the destruction of the object will happen in
the uobject destructor not the mmap free. However, I think we lack the
ability to do that right now.

Jason

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

* Re: [PATCH rdma-next v6 7/9] RDMA/bnxt_re: Enhance dpi lifecycle logic in doorbell uapis
  2026-05-19 12:46     ` Jason Gunthorpe
@ 2026-05-19 13:20       ` Sriharsha Basavapatna
  2026-05-19 13:27         ` Jason Gunthorpe
  0 siblings, 1 reply; 17+ messages in thread
From: Sriharsha Basavapatna @ 2026-05-19 13:20 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: leon, linux-rdma, andrew.gospodarek, selvin.xavier,
	kalesh-anakkur.purayil, Sriharsha Basavapatna

[-- Attachment #1: Type: text/plain, Size: 3801 bytes --]

On Tue, May 19, 2026 at 6:16 PM Jason Gunthorpe <jgg@ziepe.ca> wrote:
>
> On Tue, May 19, 2026 at 02:57:16PM +0530, Sriharsha Basavapatna wrote:
> > On Mon, May 18, 2026 at 9:17 PM Sriharsha Basavapatna
> > <sriharsha.basavapatna@broadcom.com> wrote:
> > >
> > > If the DPI is freed when the dbr object is freed, but if the
> > > process has not unmapped the page yet, then the DPI slot could
> > > get reallocated to another process while the original process
> > > still has it mapped. To prevent this, save the DPI info in the
> > > mmap entry during dbr allocation and free the DPI slot from
> > > bnxt_re_mmap_free(), which enures that there are no references
> > > to it.
> > >
> > > This change is needed to support doorbell allocation to QPs
> > > in the next patch.
> > >
> > > Signed-off-by: Sriharsha Basavapatna <sriharsha.basavapatna@broadcom.com>
> > > Reviewed-by: Selvin Xavier <selvin.xavier@broadcom.com>
> > > ---
> > >  drivers/infiniband/hw/bnxt_re/ib_verbs.c |  4 ++++
> > >  drivers/infiniband/hw/bnxt_re/ib_verbs.h |  1 +
> > >  drivers/infiniband/hw/bnxt_re/uapi.c     | 12 ++++++++++--
> > >  3 files changed, 15 insertions(+), 2 deletions(-)
> > >
> > > diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.c b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
> > > index 9fd85d81bcea..b8e46feafee7 100644
> > > --- a/drivers/infiniband/hw/bnxt_re/ib_verbs.c
> > > +++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
> > > @@ -4943,6 +4943,10 @@ void bnxt_re_mmap_free(struct rdma_user_mmap_entry *rdma_entry)
> > >         bnxt_entry = container_of(rdma_entry, struct bnxt_re_user_mmap_entry,
> > >                                   rdma_entry);
> > >
> > > +       if (bnxt_entry->mmap_flag == BNXT_RE_MMAP_UC_DB && bnxt_entry->uctx)
> > > +               bnxt_qplib_free_uc_dpi(&bnxt_entry->uctx->rdev->qplib_res,
> > > +                                      &bnxt_entry->dpi);
> > > +
> > >         kfree(bnxt_entry);
> > >  }
> > There's a sashiko warning on this change:
> >
> > "Also, does this introduce a use-after-free during device hot-unplug?
> > During hot-unplug, the RDMA core tears down the ib_ucontext (which
> > embeds bnxt_re_ucontext) synchronously. However, active VMAs outlive
> > the ucontext because hot-unplug only zaps the PTEs without closing the
> > VMAs. When the process later exits or manually unmaps the memory,
> > bnxt_re_mmap_free() is triggered. Will dereferencing
> > bnxt_entry->uctx->rdev->qplib_res result in a use-after-free since the
> > uctx has already been freed?"
>
> Hmm! That is a pretty reasonable assumption..
>
> > ufile_destroy_ucontext(reason == RDMA_REMOVE_DRIVER_REMOVE) -->
> > uverbs_user_mmap_disassociate() --> rdma_user_mmap_entry_put() -->
> > rdma_user_mmap_entry_free() --> ucontext->device->ops.mmap_free()
>
> Yes, that's right. The disassociate removes the references from all
> the VMAs so it should always eventually call free.
Ok, so disassociate() triggers mmap free in the driver while
ib_ucontext is still valid, right?  The use-after-free concern raised
above, where uctx has been freed, shouldn't occur?
>
> However, it would be best if we didn't have this code in the free
> callback at all, ideally the destruction of the object will happen in
> the uobject destructor not the mmap free. However, I think we lack the
> ability to do that right now.
>
I had to move it into mmap_free() because a prior concern pointed out
that the dpi could be reallocated to another process, while the
original process's mmap is still active.  Although the bnxt_re library
unmaps first and then destroys the dbr object (i.e in the right
sequence), I still tried to address that concern by moving it into
mmap free context.
> Jason

Thanks,
-Harsha

[-- Attachment #2: S/MIME Cryptographic Signature --]
[-- Type: application/pkcs7-signature, Size: 5505 bytes --]

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

* Re: [PATCH rdma-next v6 7/9] RDMA/bnxt_re: Enhance dpi lifecycle logic in doorbell uapis
  2026-05-19 13:20       ` Sriharsha Basavapatna
@ 2026-05-19 13:27         ` Jason Gunthorpe
  2026-05-19 13:59           ` Sriharsha Basavapatna
  0 siblings, 1 reply; 17+ messages in thread
From: Jason Gunthorpe @ 2026-05-19 13:27 UTC (permalink / raw)
  To: Sriharsha Basavapatna
  Cc: leon, linux-rdma, andrew.gospodarek, selvin.xavier,
	kalesh-anakkur.purayil

On Tue, May 19, 2026 at 06:50:38PM +0530, Sriharsha Basavapatna wrote:
> > > ufile_destroy_ucontext(reason == RDMA_REMOVE_DRIVER_REMOVE) -->
> > > uverbs_user_mmap_disassociate() --> rdma_user_mmap_entry_put() -->
> > > rdma_user_mmap_entry_free() --> ucontext->device->ops.mmap_free()
> >
> > Yes, that's right. The disassociate removes the references from all
> > the VMAs so it should always eventually call free.
> Ok, so disassociate() triggers mmap free in the driver while
> ib_ucontext is still valid, right?  The use-after-free concern raised
> above, where uctx has been freed, shouldn't occur?

As far as I can see. At least you would be in good company making this
assumption...

> > However, it would be best if we didn't have this code in the free
> > callback at all, ideally the destruction of the object will happen in
> > the uobject destructor not the mmap free. However, I think we lack the
> > ability to do that right now.
> >
> I had to move it into mmap_free() because a prior concern pointed out
> that the dpi could be reallocated to another process, while the
> original process's mmap is still active.  Although the bnxt_re library
> unmaps first and then destroys the dbr object (i.e in the right
> sequence), I still tried to address that concern by moving it into
> mmap free context.

Yes, we lack the ability to shoot down a single mmap_entry during the
uboject destruction so it has to work like this :(

Jason

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

* Re: [PATCH rdma-next v6 7/9] RDMA/bnxt_re: Enhance dpi lifecycle logic in doorbell uapis
  2026-05-19 13:27         ` Jason Gunthorpe
@ 2026-05-19 13:59           ` Sriharsha Basavapatna
  2026-05-19 14:40             ` Jason Gunthorpe
  0 siblings, 1 reply; 17+ messages in thread
From: Sriharsha Basavapatna @ 2026-05-19 13:59 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: leon, linux-rdma, andrew.gospodarek, selvin.xavier,
	kalesh-anakkur.purayil, Sriharsha Basavapatna

[-- Attachment #1: Type: text/plain, Size: 2552 bytes --]

On Tue, May 19, 2026 at 6:57 PM Jason Gunthorpe <jgg@ziepe.ca> wrote:
>
> On Tue, May 19, 2026 at 06:50:38PM +0530, Sriharsha Basavapatna wrote:
> > > > ufile_destroy_ucontext(reason == RDMA_REMOVE_DRIVER_REMOVE) -->
> > > > uverbs_user_mmap_disassociate() --> rdma_user_mmap_entry_put() -->
> > > > rdma_user_mmap_entry_free() --> ucontext->device->ops.mmap_free()
> > >
> > > Yes, that's right. The disassociate removes the references from all
> > > the VMAs so it should always eventually call free.
> > Ok, so disassociate() triggers mmap free in the driver while
> > ib_ucontext is still valid, right?  The use-after-free concern raised
> > above, where uctx has been freed, shouldn't occur?
>
> As far as I can see. At least you would be in good company making this
> assumption...
Thanks for confirmation.
>
> > > However, it would be best if we didn't have this code in the free
> > > callback at all, ideally the destruction of the object will happen in
> > > the uobject destructor not the mmap free. However, I think we lack the
> > > ability to do that right now.
> > >
> > I had to move it into mmap_free() because a prior concern pointed out
> > that the dpi could be reallocated to another process, while the
> > original process's mmap is still active.  Although the bnxt_re library
> > unmaps first and then destroys the dbr object (i.e in the right
> > sequence), I still tried to address that concern by moving it into
> > mmap free context.
>
> Yes, we lack the ability to shoot down a single mmap_entry during the
> uboject destruction so it has to work like this :(
Ok, got it.

There is another concern about exhausting/hogging DPI resources.

"Does tying the hardware DPI slot lifecycle to the VMA lifecycle allow
userspace to exhaust the hardware DPI pool? If a process allocates a
DBR object, maps it via mmap(), and then immediately destroys the DBR
object, the uverbs object is freed (replenishing the process's general
RDMA object quota). Since the active VMA keeps the mmap entry alive,
bnxt_re_mmap_free() is not called, and the hardware DPI slot is
leaked. Could a user repeat this process to hoard hardware DPI slots
until the device's entire DPI table capacity is exhausted?"

Even without this change, the DBR_ALLOC() uverb allows a process to
allocate multiple DPIs (that are meant to be distributed across QPs).
We don't want to restrict it. Again here, the library properly handles
this by unmapping and destroying each DBR object.

Thanks,
-Harsha
>
> Jason

[-- Attachment #2: S/MIME Cryptographic Signature --]
[-- Type: application/pkcs7-signature, Size: 5505 bytes --]

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

* Re: [PATCH rdma-next v6 7/9] RDMA/bnxt_re: Enhance dpi lifecycle logic in doorbell uapis
  2026-05-19 13:59           ` Sriharsha Basavapatna
@ 2026-05-19 14:40             ` Jason Gunthorpe
  2026-05-19 15:17               ` Sriharsha Basavapatna
  0 siblings, 1 reply; 17+ messages in thread
From: Jason Gunthorpe @ 2026-05-19 14:40 UTC (permalink / raw)
  To: Sriharsha Basavapatna
  Cc: leon, linux-rdma, andrew.gospodarek, selvin.xavier,
	kalesh-anakkur.purayil

On Tue, May 19, 2026 at 07:29:08PM +0530, Sriharsha Basavapatna wrote:
> "Does tying the hardware DPI slot lifecycle to the VMA lifecycle allow
> userspace to exhaust the hardware DPI pool? If a process allocates a
> DBR object, maps it via mmap(), and then immediately destroys the DBR
> object, the uverbs object is freed (replenishing the process's general
> RDMA object quota). Since the active VMA keeps the mmap entry alive,
> bnxt_re_mmap_free() is not called, and the hardware DPI slot is
> leaked. Could a user repeat this process to hoard hardware DPI slots
> until the device's entire DPI table capacity is exhausted?"

Yes that's true, but nothing you can do about this without moving the
lifecycle to the uobject, which we don't have infrastructure for.

> Even without this change, the DBR_ALLOC() uverb allows a process to
> allocate multiple DPIs (that are meant to be distributed across QPs).
> We don't want to restrict it. Again here, the library properly handles
> this by unmapping and destroying each DBR object.

Yes, but there is a cgroup limit on the number of uobjs a driver can
create, so it can be technically limited.

Jason


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

* Re: [PATCH rdma-next v6 7/9] RDMA/bnxt_re: Enhance dpi lifecycle logic in doorbell uapis
  2026-05-19 14:40             ` Jason Gunthorpe
@ 2026-05-19 15:17               ` Sriharsha Basavapatna
  0 siblings, 0 replies; 17+ messages in thread
From: Sriharsha Basavapatna @ 2026-05-19 15:17 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: leon, linux-rdma, andrew.gospodarek, selvin.xavier,
	kalesh-anakkur.purayil, Sriharsha Basavapatna

[-- Attachment #1: Type: text/plain, Size: 1757 bytes --]

On Tue, May 19, 2026 at 8:10 PM Jason Gunthorpe <jgg@ziepe.ca> wrote:
>
> On Tue, May 19, 2026 at 07:29:08PM +0530, Sriharsha Basavapatna wrote:
> > "Does tying the hardware DPI slot lifecycle to the VMA lifecycle allow
> > userspace to exhaust the hardware DPI pool? If a process allocates a
> > DBR object, maps it via mmap(), and then immediately destroys the DBR
> > object, the uverbs object is freed (replenishing the process's general
> > RDMA object quota). Since the active VMA keeps the mmap entry alive,
> > bnxt_re_mmap_free() is not called, and the hardware DPI slot is
> > leaked. Could a user repeat this process to hoard hardware DPI slots
> > until the device's entire DPI table capacity is exhausted?"
>
> Yes that's true, but nothing you can do about this without moving the
> lifecycle to the uobject, which we don't have infrastructure for.
>
> > Even without this change, the DBR_ALLOC() uverb allows a process to
> > allocate multiple DPIs (that are meant to be distributed across QPs).
> > We don't want to restrict it. Again here, the library properly handles
> > this by unmapping and destroying each DBR object.
>
> Yes, but there is a cgroup limit on the number of uobjs a driver can
> create, so it can be technically limited.

Thanks, that's good to know.

There was one other warning in v6, for which I just posted a fix in
v7. Here it is for reference:

"If BNXT_RE_MMAP_UC_DB is also used by other paths (like
bnxt_re_alloc_pd()) that do not populate entry->dpi, the
zero-initialized dpi struct will have
dpi->bit == 0. This would cause bnxt_qplib_free_uc_dpi() to
erroneously mark DPI slot 0 as free, potentially breaking hardware
doorbell isolation."

Thanks,
-Harsha
>
> Jason
>

[-- Attachment #2: S/MIME Cryptographic Signature --]
[-- Type: application/pkcs7-signature, Size: 5505 bytes --]

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

end of thread, other threads:[~2026-05-19 15:18 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-18 15:37 [PATCH rdma-next v6 0/9] RDMA/bnxt_re: Support QP uapi extensions Sriharsha Basavapatna
2026-05-18 15:37 ` [PATCH rdma-next v6 1/9] RDMA/bnxt_re: Refactor bnxt_re_init_user_qp() Sriharsha Basavapatna
2026-05-18 15:37 ` [PATCH rdma-next v6 2/9] RDMA/bnxt_re: Update rq depth for app allocated QPs Sriharsha Basavapatna
2026-05-18 15:37 ` [PATCH rdma-next v6 3/9] RDMA/bnxt_re: Update sq " Sriharsha Basavapatna
2026-05-18 15:37 ` [PATCH rdma-next v6 4/9] RDMA/bnxt_re: Update msn table size " Sriharsha Basavapatna
2026-05-18 15:37 ` [PATCH rdma-next v6 5/9] RDMA/bnxt_re: Update hwq depth " Sriharsha Basavapatna
2026-05-18 15:37 ` [PATCH rdma-next v6 6/9] RDMA/bnxt_re: Enhance dbr usecnt logic in doorbell uapis Sriharsha Basavapatna
2026-05-18 15:37 ` [PATCH rdma-next v6 7/9] RDMA/bnxt_re: Enhance dpi lifecycle " Sriharsha Basavapatna
2026-05-19  9:27   ` Sriharsha Basavapatna
2026-05-19 12:46     ` Jason Gunthorpe
2026-05-19 13:20       ` Sriharsha Basavapatna
2026-05-19 13:27         ` Jason Gunthorpe
2026-05-19 13:59           ` Sriharsha Basavapatna
2026-05-19 14:40             ` Jason Gunthorpe
2026-05-19 15:17               ` Sriharsha Basavapatna
2026-05-18 15:37 ` [PATCH rdma-next v6 8/9] RDMA/bnxt_re: Support doorbells for app allocated QPs Sriharsha Basavapatna
2026-05-18 15:37 ` [PATCH rdma-next v6 9/9] RDMA/bnxt_re: Enable " Sriharsha Basavapatna

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