[PATCH rdma-next 5/5] RDMA/irdma: Support UMEM attribute for SRQ creation
flat view
COOLING4d
SUPERSEDED
From: David Hu <hidden>
Date: 2026-10-11 01:11:38
Also in:
lkml
Subsystem:
infiniband subsystem, intel ethernet protocol driver for rdma, the rest · Maintainers:
Jason Gunthorpe, Leon Romanovsky, Tatyana Nikolova, Linus Torvalds
Revision v1 of 3 in this series.
Revisions (3)
- v1 current
- v2 [diff vs current]
- v3 [diff vs current]
From: David Hu <redacted> Support the standard 1-step queue buffer creation for SRQ by `UVERBS_ATTR_CREATE_SRQ_BUF_UMEM` via `ib_umem_get_attr()`. Set up hardware pble directly from the pinned SRQ umem via `irdma_setup_q_pbl_from_umem()`. Proper umem and pble cleanup, and error unwind are added into existing `irdma_srq_free_rsrc()` upon SRQ destruction. We maintain backward compatibility for the legacy 2-step registration if the UMEM attribute is not provided. Signed-off-by: David Hu <redacted> --- drivers/infiniband/hw/irdma/verbs.c | 68 ++++++++++++++++++++++++----- 1 file changed, 58 insertions(+), 10 deletions(-)
diff --git a/drivers/infiniband/hw/irdma/verbs.c b/drivers/infiniband/hw/irdma/verbs.c
index e4a02a6b2a11..274c76badd2e 100644
--- a/drivers/infiniband/hw/irdma/verbs.c
+++ b/drivers/infiniband/hw/irdma/verbs.c@@ -1996,9 +1996,16 @@ static void irdma_srq_free_rsrc(struct irdma_pci_f *rf, struct irdma_srq *iwsrq) iwsrq->kmem.va = NULL; } else { /* Not called in any failure path, so iwpbl is valid. */ - struct irdma_mr *iwmr = iwsrq->iwpbl->iwmr; + if (iwsrq->iwpbl) { + struct irdma_mr *iwmr = iwsrq->iwpbl->iwmr; - refcount_dec(&iwmr->user_ring_refs); + if (iwmr && refcount_dec_and_test(&iwmr->user_ring_refs)) { + ib_umem_release(iwmr->region); + if (iwsrq->iwpbl->pbl_allocated) + irdma_free_pble(rf->pble_rsrc, &iwsrq->iwpbl->pble_alloc); + kfree(iwmr); + } + } } irdma_free_rsrc(rf, rf->allocated_srqs, srq->srq_uk.srq_id);
@@ -2414,6 +2421,7 @@ static int irdma_setup_umode_srq(struct irdma_device *iwdev, struct ib_udata *udata, struct uverbs_attr_bundle *attrs) { + struct irdma_srq_uk_init_info *ukinfo = &info->srq_uk_init_info; struct irdma_create_srq_req req = {}; struct irdma_ucontext *ucontext; struct irdma_srq_mr *srqmr;
@@ -2429,14 +2437,49 @@ static int irdma_setup_umode_srq(struct irdma_device *iwdev, if (ret) return ret; - spin_lock_irqsave(&ucontext->srq_reg_mem_list_lock, flags); - iwpbl = irdma_get_pbl((unsigned long)req.user_srq_buf, - &ucontext->srq_reg_mem_list); - spin_unlock_irqrestore(&ucontext->srq_reg_mem_list_lock, flags); - if (!iwpbl) - return -EPROTO; + if (attrs && uverbs_attr_is_valid(attrs, UVERBS_ATTR_CREATE_SRQ_BUF_UMEM)) { + struct irdma_mem_reg_req srq_req = {}; + struct ib_umem *umem; + u32 total; + u8 shift; + + irdma_get_wqe_shift(ukinfo->uk_attrs, ukinfo->max_srq_frag_cnt, 0, &shift); + srq_req.rq_pages = + DIV_ROUND_UP((ukinfo->srq_size << shift) * IRDMA_QP_WQE_MIN_SIZE, + IRDMA_HW_PAGE_SIZE); + total = srq_req.rq_pages + IRDMA_SHADOW_PGCNT; + + umem = ib_umem_get_attr(&iwdev->ibdev, attrs, + UVERBS_ATTR_CREATE_SRQ_BUF_UMEM, + total << IRDMA_HW_PAGE_SHIFT, + IB_ACCESS_LOCAL_WRITE); + if (IS_ERR(umem)) + return PTR_ERR(umem); - iwsrq->iwpbl = iwpbl; + iwsrq->iwpbl = irdma_setup_q_pbl_from_umem(iwdev, umem, + iwsrq->ibsrq.pd, + IRDMA_MEMREG_TYPE_SRQ, + &srq_req); + if (IS_ERR(iwsrq->iwpbl)) { + ret = PTR_ERR(iwsrq->iwpbl); + iwsrq->iwpbl = NULL; + ib_umem_release(umem); + return ret; + } + iwpbl = iwsrq->iwpbl; + } else { + if (!req.user_srq_buf) + return -EINVAL; + + spin_lock_irqsave(&ucontext->srq_reg_mem_list_lock, flags); + iwpbl = irdma_get_pbl((unsigned long)req.user_srq_buf, + &ucontext->srq_reg_mem_list); + spin_unlock_irqrestore(&ucontext->srq_reg_mem_list_lock, flags); + if (!iwpbl) + return -EPROTO; + + iwsrq->iwpbl = iwpbl; + } srqmr = &iwpbl->srq_mr; if (iwpbl->pbl_allocated) {
@@ -2604,7 +2647,12 @@ static int irdma_create_srq(struct ib_srq *ibsrq, if (iwsrq->user_mode && iwsrq->iwpbl) { struct irdma_mr *iwmr = iwsrq->iwpbl->iwmr; - refcount_dec(&iwmr->user_ring_refs); + if (iwmr && refcount_dec_and_test(&iwmr->user_ring_refs)) { + ib_umem_release(iwmr->region); + if (iwsrq->iwpbl->pbl_allocated) + irdma_free_pble(rf->pble_rsrc, &iwsrq->iwpbl->pble_alloc); + kfree(iwmr); + } } irdma_free_rsrc(rf, rf->allocated_srqs, iwsrq->srq_num); return err_code;
--
2.56.0.385.gd3acb90ef8-goog