* [PATCH rdma-next v3 00/17] RDMA: Introduce generic buffer descriptor infrastructure for umem
@ 2026-05-04 13:57 Jiri Pirko
2026-05-04 13:57 ` [PATCH rdma-next v3 01/17] RDMA/umem: Rename ib_umem_get() to ib_umem_get_va() Jiri Pirko
` (16 more replies)
0 siblings, 17 replies; 28+ messages in thread
From: Jiri Pirko @ 2026-05-04 13:57 UTC (permalink / raw)
To: linux-rdma
Cc: jgg, leon, mrgolin, gal.pressman, sleybo, parav, mbloch,
yanjun.zhu, marco.crivellari, roman.gushchin, phaddad, lirongqing,
ynachum, huangjunxian6, kalesh-anakkur.purayil, ohartoov,
michaelgur, shayd, edwards, sriharsha.basavapatna,
andrew.gospodarek, selvin.xavier
From: Jiri Pirko <jiri@nvidia.com>
This patchset introduces a generic buffer descriptor infrastructure
for passing memory buffers (dma-buf or user VA) to uverbs commands,
and wires it up for CQ and QP creation in the uverbs core, efa, mlx5,
bnxt_re and mlx4 drivers.
Instead of adding ad-hoc per-buffer UAPI attributes for each new buffer
type, each command declares dedicated UVERBS_ATTR_UMEM attributes that
carry one buffer descriptor each. Each descriptor specifies a buffer
type, covering both VA and dma-buf. A consumption check ensures
userspace and driver agree on which attributes are used.
The patchset:
1-2,4. Plumbing: rename ib_umem_get() to ib_umem_get_va() and re-route
it through the new central ib_umem_get(); no behaviour change.
3. Introduces the core buffer descriptor infrastructure and UAPI.
5. Inlines the const attr helpers so ib_core can use them.
6. Factors out CQ buffer umem processing into a helper.
7. Adds the CQ buffer UMEM attribute and driver wrappers.
8-11. Converts efa, mlx5, bnxt_re and mlx4 to use the new CQ helpers,
with drivers taking umem ownership.
12. Removes the legacy umem field from struct ib_cq, now that all
drivers use the new helpers.
13. Adds optional whole-QP, RQ and SQ UMEM attributes to QP creation.
14. Converts mlx5 QP creation to use the new attributes.
15-16. Adds mlx5 driver-namespace UMEM attributes for CQ and QP
doorbell records.
17. Adds a CONFIG_DEBUG_KERNEL-gated tracker that warns when userspace
supplies an attribute nothing reads.
---
See individual patches for changelog.
v2: https://lore.kernel.org/all/20260411144915.114571-1-jiri@resnulli.us/
v1: https://lore.kernel.org/all/20260203085003.71184-1-jiri@resnulli.us/
Note this re-works the original patchset trying to handle this:
https://lore.kernel.org/all/20260203085003.71184-1-jiri@resnulli.us/
The code is so much different I'm sending this is a new patchset.
Jiri Pirko (17):
RDMA/umem: Rename ib_umem_get() to ib_umem_get_va()
RDMA/umem: Split ib_umem_get_va() into a thin wrapper around
__ib_umem_get_va()
RDMA/core: Introduce generic buffer descriptor infrastructure for umem
RDMA/umem: Route ib_umem_get_va() through ib_umem_get()
RDMA/uverbs: Inline _uverbs_get_const_{signed,unsigned}()
RDMA/uverbs: Push out CQ buffer umem processing into a helper
RDMA/uverbs: Add CQ buffer UMEM attribute and driver helpers
RDMA/efa: Use ib_umem_get_cq_buf() for user CQ buffer
RDMA/mlx5: Use ib_umem_get_cq_buf_or_va() for user CQ buffer
RDMA/bnxt_re: Use ib_umem_get_cq_buf_or_va() for user CQ buffer
RDMA/mlx4: Use ib_umem_get_cq_buf() for user CQ buffer
RDMA/uverbs: Remove legacy umem field from struct ib_cq
RDMA/uverbs: Use UMEM attributes for QP creation
RDMA/mlx5: Use UMEM attributes for QP buffers in create_qp
RDMA/mlx5: Use UMEM attribute for CQ doorbell record
RDMA/mlx5: Use UMEM attribute for QP doorbell record
RDMA/uverbs: Track attr consumption and warn on unused attrs
drivers/infiniband/core/rdma_core.h | 2 +-
drivers/infiniband/core/umem.c | 217 +++++++++++++++++-
drivers/infiniband/core/uverbs_cmd.c | 1 -
drivers/infiniband/core/uverbs_ioctl.c | 102 ++++----
drivers/infiniband/core/uverbs_std_types_cq.c | 73 +-----
drivers/infiniband/core/uverbs_std_types_qp.c | 6 +
drivers/infiniband/core/verbs.c | 7 -
drivers/infiniband/hw/bnxt_re/ib_verbs.c | 61 ++---
drivers/infiniband/hw/bnxt_re/ib_verbs.h | 1 +
drivers/infiniband/hw/cxgb4/mem.c | 2 +-
drivers/infiniband/hw/efa/efa_verbs.c | 29 ++-
drivers/infiniband/hw/erdma/erdma_verbs.c | 6 +-
drivers/infiniband/hw/hns/hns_roce_db.c | 4 +-
drivers/infiniband/hw/hns/hns_roce_mr.c | 4 +-
.../infiniband/hw/ionic/ionic_controlpath.c | 10 +-
drivers/infiniband/hw/irdma/verbs.c | 4 +-
drivers/infiniband/hw/mana/main.c | 2 +-
drivers/infiniband/hw/mana/mr.c | 2 +-
drivers/infiniband/hw/mlx4/cq.c | 56 +++--
drivers/infiniband/hw/mlx4/doorbell.c | 4 +-
drivers/infiniband/hw/mlx4/mlx4_ib.h | 1 +
drivers/infiniband/hw/mlx4/mr.c | 4 +-
drivers/infiniband/hw/mlx4/qp.c | 4 +-
drivers/infiniband/hw/mlx4/srq.c | 2 +-
drivers/infiniband/hw/mlx5/cq.c | 41 ++--
drivers/infiniband/hw/mlx5/devx.c | 2 +-
drivers/infiniband/hw/mlx5/doorbell.c | 55 ++++-
drivers/infiniband/hw/mlx5/main.c | 1 +
drivers/infiniband/hw/mlx5/mlx5_ib.h | 6 +-
drivers/infiniband/hw/mlx5/mr.c | 6 +-
drivers/infiniband/hw/mlx5/qp.c | 51 +++-
drivers/infiniband/hw/mlx5/srq.c | 4 +-
drivers/infiniband/hw/mthca/mthca_provider.c | 2 +-
drivers/infiniband/hw/ocrdma/ocrdma_verbs.c | 2 +-
drivers/infiniband/hw/qedr/verbs.c | 13 +-
drivers/infiniband/hw/vmw_pvrdma/pvrdma_cq.c | 4 +-
drivers/infiniband/hw/vmw_pvrdma/pvrdma_mr.c | 2 +-
drivers/infiniband/hw/vmw_pvrdma/pvrdma_qp.c | 10 +-
drivers/infiniband/hw/vmw_pvrdma/pvrdma_srq.c | 2 +-
drivers/infiniband/sw/rdmavt/mr.c | 2 +-
drivers/infiniband/sw/rxe/rxe_mr.c | 2 +-
drivers/infiniband/sw/siw/siw_mem.c | 2 +-
include/rdma/ib_umem.h | 89 ++++++-
include/rdma/ib_verbs.h | 1 -
include/rdma/uverbs_ioctl.h | 113 ++++++---
include/uapi/rdma/ib_user_ioctl_cmds.h | 4 +
include/uapi/rdma/ib_user_ioctl_verbs.h | 23 ++
include/uapi/rdma/mlx5_user_ioctl_cmds.h | 5 +
48 files changed, 717 insertions(+), 329 deletions(-)
--
2.53.0
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH rdma-next v3 01/17] RDMA/umem: Rename ib_umem_get() to ib_umem_get_va()
2026-05-04 13:57 [PATCH rdma-next v3 00/17] RDMA: Introduce generic buffer descriptor infrastructure for umem Jiri Pirko
@ 2026-05-04 13:57 ` Jiri Pirko
2026-05-04 13:57 ` [PATCH rdma-next v3 02/17] RDMA/umem: Split ib_umem_get_va() into a thin wrapper around __ib_umem_get_va() Jiri Pirko
` (15 subsequent siblings)
16 siblings, 0 replies; 28+ messages in thread
From: Jiri Pirko @ 2026-05-04 13:57 UTC (permalink / raw)
To: linux-rdma
Cc: jgg, leon, mrgolin, gal.pressman, sleybo, parav, mbloch,
yanjun.zhu, marco.crivellari, roman.gushchin, phaddad, lirongqing,
ynachum, huangjunxian6, kalesh-anakkur.purayil, ohartoov,
michaelgur, shayd, edwards, sriharsha.basavapatna,
andrew.gospodarek, selvin.xavier
From: Jiri Pirko <jiri@nvidia.com>
The new umem getter family being introduced in follow-up patches
need a fitting name for the central all-source helper that resolves
attributes, legacy fillers and a UHW VA fallback.
Rename the existing VA-pinning helper ib_umem_get() to ib_umem_get_va()
so the name is freed up. The new name is consistent with names of rest
of the helpers that are about to be introduced.
Signed-off-by: Jiri Pirko <jiri@nvidia.com>
---
v2->v3:
- new patch
---
drivers/infiniband/core/umem.c | 10 +++----
drivers/infiniband/core/uverbs_std_types_cq.c | 2 +-
drivers/infiniband/hw/bnxt_re/ib_verbs.c | 28 +++++++++----------
drivers/infiniband/hw/cxgb4/mem.c | 2 +-
drivers/infiniband/hw/efa/efa_verbs.c | 2 +-
drivers/infiniband/hw/erdma/erdma_verbs.c | 6 ++--
drivers/infiniband/hw/hns/hns_roce_db.c | 4 +--
drivers/infiniband/hw/hns/hns_roce_mr.c | 4 +--
.../infiniband/hw/ionic/ionic_controlpath.c | 10 +++----
drivers/infiniband/hw/irdma/verbs.c | 4 +--
drivers/infiniband/hw/mana/main.c | 2 +-
drivers/infiniband/hw/mana/mr.c | 2 +-
drivers/infiniband/hw/mlx4/cq.c | 12 ++++----
drivers/infiniband/hw/mlx4/doorbell.c | 4 +--
drivers/infiniband/hw/mlx4/mr.c | 4 +--
drivers/infiniband/hw/mlx4/qp.c | 4 +--
drivers/infiniband/hw/mlx4/srq.c | 2 +-
drivers/infiniband/hw/mlx5/cq.c | 12 ++++----
drivers/infiniband/hw/mlx5/devx.c | 2 +-
drivers/infiniband/hw/mlx5/doorbell.c | 4 +--
drivers/infiniband/hw/mlx5/mr.c | 6 ++--
drivers/infiniband/hw/mlx5/qp.c | 10 +++----
drivers/infiniband/hw/mlx5/srq.c | 2 +-
drivers/infiniband/hw/mthca/mthca_provider.c | 2 +-
drivers/infiniband/hw/ocrdma/ocrdma_verbs.c | 2 +-
drivers/infiniband/hw/qedr/verbs.c | 13 +++++----
drivers/infiniband/hw/vmw_pvrdma/pvrdma_cq.c | 4 +--
drivers/infiniband/hw/vmw_pvrdma/pvrdma_mr.c | 2 +-
drivers/infiniband/hw/vmw_pvrdma/pvrdma_qp.c | 10 +++----
drivers/infiniband/hw/vmw_pvrdma/pvrdma_srq.c | 2 +-
drivers/infiniband/sw/rdmavt/mr.c | 2 +-
drivers/infiniband/sw/rxe/rxe_mr.c | 2 +-
drivers/infiniband/sw/siw/siw_mem.c | 2 +-
include/rdma/ib_umem.h | 10 +++----
34 files changed, 95 insertions(+), 94 deletions(-)
diff --git a/drivers/infiniband/core/umem.c b/drivers/infiniband/core/umem.c
index 7615d9d7fdfa..986f785a37cd 100644
--- a/drivers/infiniband/core/umem.c
+++ b/drivers/infiniband/core/umem.c
@@ -154,15 +154,15 @@ unsigned long ib_umem_find_best_pgsz(struct ib_umem *umem,
EXPORT_SYMBOL(ib_umem_find_best_pgsz);
/**
- * ib_umem_get - Pin and DMA map userspace memory.
+ * ib_umem_get_va - Pin and DMA map userspace memory.
*
* @device: IB device to connect UMEM
* @addr: userspace virtual address to start at
* @size: length of region to pin
* @access: IB_ACCESS_xxx flags for memory being pinned
*/
-struct ib_umem *ib_umem_get(struct ib_device *device, unsigned long addr,
- size_t size, int access)
+struct ib_umem *ib_umem_get_va(struct ib_device *device, unsigned long addr,
+ size_t size, int access)
{
struct ib_umem *umem;
struct page **page_list;
@@ -278,10 +278,10 @@ struct ib_umem *ib_umem_get(struct ib_device *device, unsigned long addr,
}
return ret ? ERR_PTR(ret) : umem;
}
-EXPORT_SYMBOL(ib_umem_get);
+EXPORT_SYMBOL(ib_umem_get_va);
/**
- * ib_umem_release - release memory pinned with ib_umem_get
+ * ib_umem_release - release pinned memory
* @umem: umem struct to release
*/
void ib_umem_release(struct ib_umem *umem)
diff --git a/drivers/infiniband/core/uverbs_std_types_cq.c b/drivers/infiniband/core/uverbs_std_types_cq.c
index 79b51f60ce2a..1a6bc8baa52b 100644
--- a/drivers/infiniband/core/uverbs_std_types_cq.c
+++ b/drivers/infiniband/core/uverbs_std_types_cq.c
@@ -139,7 +139,7 @@ static int UVERBS_HANDLER(UVERBS_METHOD_CQ_CREATE)(
goto err_event_file;
}
- umem = ib_umem_get(ib_dev, buffer_va, buffer_length, IB_ACCESS_LOCAL_WRITE);
+ umem = ib_umem_get_va(ib_dev, buffer_va, buffer_length, IB_ACCESS_LOCAL_WRITE);
if (IS_ERR(umem)) {
ret = PTR_ERR(umem);
goto err_event_file;
diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.c b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
index 7ed294516b7e..1f626b7c6af2 100644
--- a/drivers/infiniband/hw/bnxt_re/ib_verbs.c
+++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
@@ -1166,8 +1166,8 @@ static int bnxt_re_init_user_qp(struct bnxt_re_dev *rdev, struct bnxt_re_pd *pd,
}
bytes = PAGE_ALIGN(bytes);
- umem = ib_umem_get(&rdev->ibdev, ureq->qpsva, bytes,
- IB_ACCESS_LOCAL_WRITE);
+ umem = ib_umem_get_va(&rdev->ibdev, ureq->qpsva, bytes,
+ IB_ACCESS_LOCAL_WRITE);
if (IS_ERR(umem))
return PTR_ERR(umem);
@@ -1180,8 +1180,8 @@ static int bnxt_re_init_user_qp(struct bnxt_re_dev *rdev, struct bnxt_re_pd *pd,
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);
+ umem = ib_umem_get_va(&rdev->ibdev, ureq->qprva, bytes,
+ IB_ACCESS_LOCAL_WRITE);
if (IS_ERR(umem))
goto rqfail;
qp->rumem = umem;
@@ -2058,8 +2058,8 @@ static int bnxt_re_init_user_srq(struct bnxt_re_dev *rdev,
bytes = (qplib_srq->max_wqe * qplib_srq->wqe_size);
bytes = PAGE_ALIGN(bytes);
- umem = ib_umem_get(&rdev->ibdev, ureq.srqva, bytes,
- IB_ACCESS_LOCAL_WRITE);
+ umem = ib_umem_get_va(&rdev->ibdev, ureq.srqva, bytes,
+ IB_ACCESS_LOCAL_WRITE);
if (IS_ERR(umem))
return PTR_ERR(umem);
@@ -3403,9 +3403,9 @@ int bnxt_re_create_user_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *att
dev_attr->max_cq_wqes + 1, uctx);
if (!ibcq->umem) {
- ibcq->umem = ib_umem_get(&rdev->ibdev, req.cq_va,
- entries * sizeof(struct cq_base),
- IB_ACCESS_LOCAL_WRITE);
+ ibcq->umem = ib_umem_get_va(&rdev->ibdev, req.cq_va,
+ entries * sizeof(struct cq_base),
+ IB_ACCESS_LOCAL_WRITE);
if (IS_ERR(ibcq->umem))
return PTR_ERR(ibcq->umem);
}
@@ -3562,12 +3562,12 @@ int bnxt_re_resize_cq(struct ib_cq *ibcq, unsigned int cqe,
if (rc)
goto fail;
- cq->resize_umem = ib_umem_get(&rdev->ibdev, req.cq_va,
- entries * sizeof(struct cq_base),
- IB_ACCESS_LOCAL_WRITE);
+ cq->resize_umem = ib_umem_get_va(&rdev->ibdev, req.cq_va,
+ entries * sizeof(struct cq_base),
+ IB_ACCESS_LOCAL_WRITE);
if (IS_ERR(cq->resize_umem)) {
rc = PTR_ERR(cq->resize_umem);
- ibdev_err(&rdev->ibdev, "%s: ib_umem_get failed! rc = %pe\n",
+ ibdev_err(&rdev->ibdev, "%s: ib_umem_get_va failed! rc = %pe\n",
__func__, cq->resize_umem);
cq->resize_umem = NULL;
goto fail;
@@ -4577,7 +4577,7 @@ struct ib_mr *bnxt_re_reg_user_mr(struct ib_pd *ib_pd, u64 start, u64 length,
if (dmah)
return ERR_PTR(-EOPNOTSUPP);
- umem = ib_umem_get(&rdev->ibdev, start, length, mr_access_flags);
+ umem = ib_umem_get_va(&rdev->ibdev, start, length, mr_access_flags);
if (IS_ERR(umem))
return ERR_CAST(umem);
diff --git a/drivers/infiniband/hw/cxgb4/mem.c b/drivers/infiniband/hw/cxgb4/mem.c
index 9fde78b74690..cd1b01014198 100644
--- a/drivers/infiniband/hw/cxgb4/mem.c
+++ b/drivers/infiniband/hw/cxgb4/mem.c
@@ -530,7 +530,7 @@ struct ib_mr *c4iw_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
mhp->rhp = rhp;
- mhp->umem = ib_umem_get(pd->device, start, length, acc);
+ mhp->umem = ib_umem_get_va(pd->device, start, length, acc);
if (IS_ERR(mhp->umem))
goto err_free_skb;
diff --git a/drivers/infiniband/hw/efa/efa_verbs.c b/drivers/infiniband/hw/efa/efa_verbs.c
index 7bd0838ebc99..e103d1654a69 100644
--- a/drivers/infiniband/hw/efa/efa_verbs.c
+++ b/drivers/infiniband/hw/efa/efa_verbs.c
@@ -1774,7 +1774,7 @@ struct ib_mr *efa_reg_mr(struct ib_pd *ibpd, u64 start, u64 length,
goto err_out;
}
- mr->umem = ib_umem_get(ibpd->device, start, length, access_flags);
+ mr->umem = ib_umem_get_va(ibpd->device, start, length, access_flags);
if (IS_ERR(mr->umem)) {
err = PTR_ERR(mr->umem);
ibdev_dbg(&dev->ibdev,
diff --git a/drivers/infiniband/hw/erdma/erdma_verbs.c b/drivers/infiniband/hw/erdma/erdma_verbs.c
index 5523b4e151e1..b229064ea48c 100644
--- a/drivers/infiniband/hw/erdma/erdma_verbs.c
+++ b/drivers/infiniband/hw/erdma/erdma_verbs.c
@@ -829,7 +829,7 @@ static int get_mtt_entries(struct erdma_dev *dev, struct erdma_mem *mem,
{
int ret = 0;
- mem->umem = ib_umem_get(&dev->ibdev, start, len, access);
+ mem->umem = ib_umem_get_va(&dev->ibdev, start, len, access);
if (IS_ERR(mem->umem)) {
ret = PTR_ERR(mem->umem);
mem->umem = NULL;
@@ -896,8 +896,8 @@ static int erdma_map_user_dbrecords(struct erdma_ucontext *ctx,
page->va = (dbrecords_va & PAGE_MASK);
page->refcnt = 0;
- page->umem = ib_umem_get(ctx->ibucontext.device,
- dbrecords_va & PAGE_MASK, PAGE_SIZE, 0);
+ page->umem = ib_umem_get_va(ctx->ibucontext.device,
+ dbrecords_va & PAGE_MASK, PAGE_SIZE, 0);
if (IS_ERR(page->umem)) {
rv = PTR_ERR(page->umem);
kfree(page);
diff --git a/drivers/infiniband/hw/hns/hns_roce_db.c b/drivers/infiniband/hw/hns/hns_roce_db.c
index f64023f5cf0a..5e008a1700ef 100644
--- a/drivers/infiniband/hw/hns/hns_roce_db.c
+++ b/drivers/infiniband/hw/hns/hns_roce_db.c
@@ -29,8 +29,8 @@ int hns_roce_db_map_user(struct hns_roce_ucontext *context, unsigned long virt,
refcount_set(&page->refcount, 1);
page->user_virt = page_addr;
- page->umem = ib_umem_get(context->ibucontext.device, page_addr,
- PAGE_SIZE, 0);
+ page->umem = ib_umem_get_va(context->ibucontext.device, page_addr,
+ PAGE_SIZE, 0);
if (IS_ERR(page->umem)) {
ret = PTR_ERR(page->umem);
kfree(page);
diff --git a/drivers/infiniband/hw/hns/hns_roce_mr.c b/drivers/infiniband/hw/hns/hns_roce_mr.c
index 896af1828a38..5c70cb20eabd 100644
--- a/drivers/infiniband/hw/hns/hns_roce_mr.c
+++ b/drivers/infiniband/hw/hns/hns_roce_mr.c
@@ -591,8 +591,8 @@ static int mtr_alloc_bufs(struct hns_roce_dev *hr_dev, struct hns_roce_mtr *mtr,
if (udata) {
mtr->kmem = NULL;
- mtr->umem = ib_umem_get(ibdev, user_addr, total_size,
- buf_attr->user_access);
+ mtr->umem = ib_umem_get_va(ibdev, user_addr, total_size,
+ buf_attr->user_access);
if (IS_ERR(mtr->umem)) {
ibdev_err(ibdev, "failed to get umem, ret = %pe.\n",
mtr->umem);
diff --git a/drivers/infiniband/hw/ionic/ionic_controlpath.c b/drivers/infiniband/hw/ionic/ionic_controlpath.c
index 7051a81cca94..d4ac6b116a80 100644
--- a/drivers/infiniband/hw/ionic/ionic_controlpath.c
+++ b/drivers/infiniband/hw/ionic/ionic_controlpath.c
@@ -110,8 +110,8 @@ int ionic_create_cq_common(struct ionic_vcq *vcq,
if (rc)
goto err_qdesc;
- cq->umem = ib_umem_get(&dev->ibdev, req_cq->addr, req_cq->size,
- IB_ACCESS_LOCAL_WRITE);
+ cq->umem = ib_umem_get_va(&dev->ibdev, req_cq->addr,
+ req_cq->size, IB_ACCESS_LOCAL_WRITE);
if (IS_ERR(cq->umem)) {
rc = PTR_ERR(cq->umem);
goto err_qdesc;
@@ -895,7 +895,7 @@ struct ib_mr *ionic_reg_user_mr(struct ib_pd *ibpd, u64 start, u64 length,
mr->flags = IONIC_MRF_USER_MR | to_ionic_mr_flags(access);
- mr->umem = ib_umem_get(&dev->ibdev, start, length, access);
+ mr->umem = ib_umem_get_va(&dev->ibdev, start, length, access);
if (IS_ERR(mr->umem)) {
rc = PTR_ERR(mr->umem);
goto err_umem;
@@ -1837,7 +1837,7 @@ static int ionic_qp_sq_init(struct ionic_ibdev *dev, struct ionic_ctx *ctx,
qp->sq_meta = NULL;
qp->sq_msn_idx = NULL;
- qp->sq_umem = ib_umem_get(&dev->ibdev, sq->addr, sq->size, 0);
+ qp->sq_umem = ib_umem_get_va(&dev->ibdev, sq->addr, sq->size, 0);
if (IS_ERR(qp->sq_umem))
return PTR_ERR(qp->sq_umem);
} else {
@@ -2050,7 +2050,7 @@ static int ionic_qp_rq_init(struct ionic_ibdev *dev, struct ionic_ctx *ctx,
qp->rq_meta = NULL;
- qp->rq_umem = ib_umem_get(&dev->ibdev, rq->addr, rq->size, 0);
+ qp->rq_umem = ib_umem_get_va(&dev->ibdev, rq->addr, rq->size, 0);
if (IS_ERR(qp->rq_umem))
return PTR_ERR(qp->rq_umem);
} else {
diff --git a/drivers/infiniband/hw/irdma/verbs.c b/drivers/infiniband/hw/irdma/verbs.c
index 17086048d2d7..11ea4f649681 100644
--- a/drivers/infiniband/hw/irdma/verbs.c
+++ b/drivers/infiniband/hw/irdma/verbs.c
@@ -3537,7 +3537,7 @@ static struct ib_mr *irdma_reg_user_mr(struct ib_pd *pd, u64 start, u64 len,
if (udata->inlen < IRDMA_MEM_REG_MIN_REQ_LEN)
return ERR_PTR(-EINVAL);
- region = ib_umem_get(pd->device, start, len, access);
+ region = ib_umem_get_va(pd->device, start, len, access);
if (IS_ERR(region)) {
ibdev_dbg(&iwdev->ibdev,
@@ -3739,7 +3739,7 @@ static int irdma_rereg_mr_trans(struct irdma_mr *iwmr, u64 start, u64 len,
struct ib_umem *region;
int err;
- region = ib_umem_get(pd->device, start, len, iwmr->access);
+ region = ib_umem_get_va(pd->device, start, len, iwmr->access);
if (IS_ERR(region))
return PTR_ERR(region);
diff --git a/drivers/infiniband/hw/mana/main.c b/drivers/infiniband/hw/mana/main.c
index ac5e75dd3494..6c3c436ad731 100644
--- a/drivers/infiniband/hw/mana/main.c
+++ b/drivers/infiniband/hw/mana/main.c
@@ -238,7 +238,7 @@ int mana_ib_create_queue(struct mana_ib_dev *mdev, u64 addr, u32 size,
queue->id = INVALID_QUEUE_ID;
queue->gdma_region = GDMA_INVALID_DMA_REGION;
- umem = ib_umem_get(&mdev->ib_dev, addr, size, IB_ACCESS_LOCAL_WRITE);
+ umem = ib_umem_get_va(&mdev->ib_dev, addr, size, IB_ACCESS_LOCAL_WRITE);
if (IS_ERR(umem)) {
ibdev_dbg(&mdev->ib_dev, "Failed to get umem, %pe\n", umem);
return PTR_ERR(umem);
diff --git a/drivers/infiniband/hw/mana/mr.c b/drivers/infiniband/hw/mana/mr.c
index 8092a7bb785b..030bfdcfff3c 100644
--- a/drivers/infiniband/hw/mana/mr.c
+++ b/drivers/infiniband/hw/mana/mr.c
@@ -127,7 +127,7 @@ struct ib_mr *mana_ib_reg_user_mr(struct ib_pd *ibpd, u64 start, u64 length,
if (!mr)
return ERR_PTR(-ENOMEM);
- mr->umem = ib_umem_get(ibdev, start, length, access_flags);
+ mr->umem = ib_umem_get_va(ibdev, start, length, access_flags);
if (IS_ERR(mr->umem)) {
err = PTR_ERR(mr->umem);
ibdev_dbg(ibdev,
diff --git a/drivers/infiniband/hw/mlx4/cq.c b/drivers/infiniband/hw/mlx4/cq.c
index 7a6eb602d4a6..381c7dfa4667 100644
--- a/drivers/infiniband/hw/mlx4/cq.c
+++ b/drivers/infiniband/hw/mlx4/cq.c
@@ -179,9 +179,9 @@ int mlx4_ib_create_user_cq(struct ib_cq *ibcq,
buf_addr = (void *)(unsigned long)ucmd.buf_addr;
if (!ibcq->umem)
- ibcq->umem = ib_umem_get(&dev->ib_dev, ucmd.buf_addr,
- entries * cqe_size,
- IB_ACCESS_LOCAL_WRITE);
+ ibcq->umem = ib_umem_get_va(&dev->ib_dev, ucmd.buf_addr,
+ entries * cqe_size,
+ IB_ACCESS_LOCAL_WRITE);
if (IS_ERR(ibcq->umem)) {
err = PTR_ERR(ibcq->umem);
goto err_cq;
@@ -343,9 +343,9 @@ static int mlx4_alloc_resize_umem(struct mlx4_ib_dev *dev, struct mlx4_ib_cq *cq
if (!cq->resize_buf)
return -ENOMEM;
- cq->resize_umem = ib_umem_get(&dev->ib_dev, ucmd.buf_addr,
- entries * cqe_size,
- IB_ACCESS_LOCAL_WRITE);
+ cq->resize_umem = ib_umem_get_va(&dev->ib_dev, ucmd.buf_addr,
+ entries * cqe_size,
+ IB_ACCESS_LOCAL_WRITE);
if (IS_ERR(cq->resize_umem)) {
err = PTR_ERR(cq->resize_umem);
goto err_buf;
diff --git a/drivers/infiniband/hw/mlx4/doorbell.c b/drivers/infiniband/hw/mlx4/doorbell.c
index 8ba86b1e4e46..22ae728834fc 100644
--- a/drivers/infiniband/hw/mlx4/doorbell.c
+++ b/drivers/infiniband/hw/mlx4/doorbell.c
@@ -64,8 +64,8 @@ int mlx4_ib_db_map_user(struct ib_udata *udata, unsigned long virt,
page->user_virt = (virt & PAGE_MASK);
page->refcnt = 0;
- page->umem = ib_umem_get(context->ibucontext.device, virt & PAGE_MASK,
- PAGE_SIZE, 0);
+ page->umem = ib_umem_get_va(context->ibucontext.device,
+ virt & PAGE_MASK, PAGE_SIZE, 0);
if (IS_ERR(page->umem)) {
err = PTR_ERR(page->umem);
kfree(page);
diff --git a/drivers/infiniband/hw/mlx4/mr.c b/drivers/infiniband/hw/mlx4/mr.c
index 650b4a9121ff..027ffb6f79d3 100644
--- a/drivers/infiniband/hw/mlx4/mr.c
+++ b/drivers/infiniband/hw/mlx4/mr.c
@@ -110,7 +110,7 @@ static struct ib_umem *mlx4_get_umem_mr(struct ib_device *device, u64 start,
/*
* Force registering the memory as writable if the underlying pages
* are writable. This is so rereg can change the access permissions
- * from readable to writable without having to run through ib_umem_get
+ * from readable to writable without having to run through ib_umem_get_va
* again
*/
if (!ib_access_writable(access_flags)) {
@@ -135,7 +135,7 @@ static struct ib_umem *mlx4_get_umem_mr(struct ib_device *device, u64 start,
mmap_read_unlock(current->mm);
}
- return ib_umem_get(device, start, length, access_flags);
+ return ib_umem_get_va(device, start, length, access_flags);
}
struct ib_mr *mlx4_ib_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c
index 790be09d985a..491bcaed9eca 100644
--- a/drivers/infiniband/hw/mlx4/qp.c
+++ b/drivers/infiniband/hw/mlx4/qp.c
@@ -897,7 +897,7 @@ static int create_rq(struct ib_pd *pd, struct ib_qp_init_attr *init_attr,
qp->buf_size = (qp->rq.wqe_cnt << qp->rq.wqe_shift) +
(qp->sq.wqe_cnt << qp->sq.wqe_shift);
- qp->umem = ib_umem_get(pd->device, wq.buf_addr, qp->buf_size, 0);
+ qp->umem = ib_umem_get_va(pd->device, wq.buf_addr, qp->buf_size, 0);
if (IS_ERR(qp->umem)) {
err = PTR_ERR(qp->umem);
goto err;
@@ -1080,7 +1080,7 @@ static int create_qp_common(struct ib_pd *pd, struct ib_qp_init_attr *init_attr,
goto err;
qp->umem =
- ib_umem_get(pd->device, ucmd.buf_addr, qp->buf_size, 0);
+ ib_umem_get_va(pd->device, ucmd.buf_addr, qp->buf_size, 0);
if (IS_ERR(qp->umem)) {
err = PTR_ERR(qp->umem);
goto err;
diff --git a/drivers/infiniband/hw/mlx4/srq.c b/drivers/infiniband/hw/mlx4/srq.c
index 5b23e5f8b84a..4c13355e14ce 100644
--- a/drivers/infiniband/hw/mlx4/srq.c
+++ b/drivers/infiniband/hw/mlx4/srq.c
@@ -116,7 +116,7 @@ int mlx4_ib_create_srq(struct ib_srq *ib_srq,
return err;
srq->umem =
- ib_umem_get(ib_srq->device, ucmd.buf_addr, buf_size, 0);
+ ib_umem_get_va(ib_srq->device, ucmd.buf_addr, buf_size, 0);
if (IS_ERR(srq->umem))
return PTR_ERR(srq->umem);
diff --git a/drivers/infiniband/hw/mlx5/cq.c b/drivers/infiniband/hw/mlx5/cq.c
index a76b7a36087d..b8a4a69c5686 100644
--- a/drivers/infiniband/hw/mlx5/cq.c
+++ b/drivers/infiniband/hw/mlx5/cq.c
@@ -746,9 +746,9 @@ static int create_cq_user(struct mlx5_ib_dev *dev, struct ib_udata *udata,
*cqe_size = ucmd.cqe_size;
if (!cq->ibcq.umem)
- cq->ibcq.umem = ib_umem_get(&dev->ib_dev, ucmd.buf_addr,
- entries * ucmd.cqe_size,
- IB_ACCESS_LOCAL_WRITE);
+ cq->ibcq.umem = ib_umem_get_va(&dev->ib_dev, ucmd.buf_addr,
+ entries * ucmd.cqe_size,
+ IB_ACCESS_LOCAL_WRITE);
if (IS_ERR(cq->ibcq.umem))
return PTR_ERR(cq->ibcq.umem);
@@ -1240,9 +1240,9 @@ static int resize_user(struct mlx5_ib_dev *dev, struct mlx5_ib_cq *cq,
if (ucmd.cqe_size && SIZE_MAX / ucmd.cqe_size <= entries - 1)
return -EINVAL;
- umem = ib_umem_get(&dev->ib_dev, ucmd.buf_addr,
- (size_t)ucmd.cqe_size * entries,
- IB_ACCESS_LOCAL_WRITE);
+ umem = ib_umem_get_va(&dev->ib_dev, ucmd.buf_addr,
+ (size_t)ucmd.cqe_size * entries,
+ IB_ACCESS_LOCAL_WRITE);
if (IS_ERR(umem)) {
err = PTR_ERR(umem);
return err;
diff --git a/drivers/infiniband/hw/mlx5/devx.c b/drivers/infiniband/hw/mlx5/devx.c
index 645ebcc0832d..7a13c2300a59 100644
--- a/drivers/infiniband/hw/mlx5/devx.c
+++ b/drivers/infiniband/hw/mlx5/devx.c
@@ -2271,7 +2271,7 @@ static int devx_umem_get(struct mlx5_ib_dev *dev, struct ib_ucontext *ucontext,
return PTR_ERR(umem_dmabuf);
obj->umem = &umem_dmabuf->umem;
} else {
- obj->umem = ib_umem_get(&dev->ib_dev, addr, size, access_flags);
+ obj->umem = ib_umem_get_va(&dev->ib_dev, addr, size, access_flags);
if (IS_ERR(obj->umem))
return PTR_ERR(obj->umem);
}
diff --git a/drivers/infiniband/hw/mlx5/doorbell.c b/drivers/infiniband/hw/mlx5/doorbell.c
index bd68fcf011f4..020c70328663 100644
--- a/drivers/infiniband/hw/mlx5/doorbell.c
+++ b/drivers/infiniband/hw/mlx5/doorbell.c
@@ -66,8 +66,8 @@ int mlx5_ib_db_map_user(struct mlx5_ib_ucontext *context, unsigned long virt,
page->user_virt = (virt & PAGE_MASK);
page->refcnt = 0;
- page->umem = ib_umem_get(context->ibucontext.device, virt & PAGE_MASK,
- PAGE_SIZE, 0);
+ page->umem = ib_umem_get_va(context->ibucontext.device,
+ virt & PAGE_MASK, PAGE_SIZE, 0);
if (IS_ERR(page->umem)) {
err = PTR_ERR(page->umem);
kfree(page);
diff --git a/drivers/infiniband/hw/mlx5/mr.c b/drivers/infiniband/hw/mlx5/mr.c
index 3b6da45061a5..fe26b3d24a75 100644
--- a/drivers/infiniband/hw/mlx5/mr.c
+++ b/drivers/infiniband/hw/mlx5/mr.c
@@ -874,7 +874,7 @@ struct ib_mr *mlx5_ib_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
if (access_flags & IB_ACCESS_ON_DEMAND)
return create_user_odp_mr(pd, start, length, iova, access_flags,
udata);
- umem = ib_umem_get(&dev->ib_dev, start, length, access_flags);
+ umem = ib_umem_get_va(&dev->ib_dev, start, length, access_flags);
if (IS_ERR(umem))
return ERR_CAST(umem);
return create_real_mr(pd, umem, iova, access_flags, dmah);
@@ -1227,8 +1227,8 @@ struct ib_mr *mlx5_ib_rereg_user_mr(struct ib_mr *ib_mr, int flags, u64 start,
struct ib_umem *new_umem;
unsigned long page_size;
- new_umem = ib_umem_get(&dev->ib_dev, start, length,
- new_access_flags);
+ new_umem = ib_umem_get_va(&dev->ib_dev, start, length,
+ new_access_flags);
if (IS_ERR(new_umem))
return ERR_CAST(new_umem);
diff --git a/drivers/infiniband/hw/mlx5/qp.c b/drivers/infiniband/hw/mlx5/qp.c
index 8f50e7342a76..1bc279d14749 100644
--- a/drivers/infiniband/hw/mlx5/qp.c
+++ b/drivers/infiniband/hw/mlx5/qp.c
@@ -890,7 +890,7 @@ static int create_user_rq(struct mlx5_ib_dev *dev, struct ib_pd *pd,
if (!ucmd->buf_addr)
return -EINVAL;
- rwq->umem = ib_umem_get(&dev->ib_dev, ucmd->buf_addr, rwq->buf_size, 0);
+ rwq->umem = ib_umem_get_va(&dev->ib_dev, ucmd->buf_addr, rwq->buf_size, 0);
if (IS_ERR(rwq->umem)) {
mlx5_ib_dbg(dev, "umem_get failed\n");
err = PTR_ERR(rwq->umem);
@@ -1000,8 +1000,8 @@ static int _create_user_qp(struct mlx5_ib_dev *dev, struct ib_pd *pd,
if (ucmd->buf_addr && ubuffer->buf_size) {
ubuffer->buf_addr = ucmd->buf_addr;
- ubuffer->umem = ib_umem_get(&dev->ib_dev, ubuffer->buf_addr,
- ubuffer->buf_size, 0);
+ ubuffer->umem = ib_umem_get_va(&dev->ib_dev, ubuffer->buf_addr,
+ ubuffer->buf_size, 0);
if (IS_ERR(ubuffer->umem)) {
err = PTR_ERR(ubuffer->umem);
goto err_bfreg;
@@ -1352,8 +1352,8 @@ static int create_raw_packet_qp_sq(struct mlx5_ib_dev *dev,
if (ts_format < 0)
return ts_format;
- sq->ubuffer.umem = ib_umem_get(&dev->ib_dev, ubuffer->buf_addr,
- ubuffer->buf_size, 0);
+ sq->ubuffer.umem = ib_umem_get_va(&dev->ib_dev, ubuffer->buf_addr,
+ ubuffer->buf_size, 0);
if (IS_ERR(sq->ubuffer.umem))
return PTR_ERR(sq->ubuffer.umem);
page_size = mlx5_umem_find_best_quantized_pgoff(
diff --git a/drivers/infiniband/hw/mlx5/srq.c b/drivers/infiniband/hw/mlx5/srq.c
index 852f6f502d14..bc22036d7e80 100644
--- a/drivers/infiniband/hw/mlx5/srq.c
+++ b/drivers/infiniband/hw/mlx5/srq.c
@@ -66,7 +66,7 @@ static int create_srq_user(struct ib_pd *pd, struct mlx5_ib_srq *srq,
srq->wq_sig = !!(ucmd.flags & MLX5_SRQ_FLAG_SIGNATURE);
- srq->umem = ib_umem_get(pd->device, ucmd.buf_addr, buf_size, 0);
+ srq->umem = ib_umem_get_va(pd->device, ucmd.buf_addr, buf_size, 0);
if (IS_ERR(srq->umem)) {
mlx5_ib_dbg(dev, "failed umem get, size %d\n", buf_size);
err = PTR_ERR(srq->umem);
diff --git a/drivers/infiniband/hw/mthca/mthca_provider.c b/drivers/infiniband/hw/mthca/mthca_provider.c
index e8d5d865c1f1..b099857dca16 100644
--- a/drivers/infiniband/hw/mthca/mthca_provider.c
+++ b/drivers/infiniband/hw/mthca/mthca_provider.c
@@ -864,7 +864,7 @@ static struct ib_mr *mthca_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
if (!mr)
return ERR_PTR(-ENOMEM);
- mr->umem = ib_umem_get(pd->device, start, length, acc);
+ mr->umem = ib_umem_get_va(pd->device, start, length, acc);
if (IS_ERR(mr->umem)) {
err = PTR_ERR(mr->umem);
goto err;
diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
index c17e2a54dbca..7ac0480edcec 100644
--- a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
+++ b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
@@ -865,7 +865,7 @@ struct ib_mr *ocrdma_reg_user_mr(struct ib_pd *ibpd, u64 start, u64 len,
mr = kzalloc_obj(*mr);
if (!mr)
return ERR_PTR(status);
- mr->umem = ib_umem_get(ibpd->device, start, len, acc);
+ mr->umem = ib_umem_get_va(ibpd->device, start, len, acc);
if (IS_ERR(mr->umem)) {
status = -EFAULT;
goto umem_err;
diff --git a/drivers/infiniband/hw/qedr/verbs.c b/drivers/infiniband/hw/qedr/verbs.c
index 679aa6f3a63b..56d2c3d41ef4 100644
--- a/drivers/infiniband/hw/qedr/verbs.c
+++ b/drivers/infiniband/hw/qedr/verbs.c
@@ -796,9 +796,9 @@ static inline int qedr_init_user_queue(struct ib_udata *udata,
q->buf_addr = buf_addr;
q->buf_len = buf_len;
- q->umem = ib_umem_get(&dev->ibdev, q->buf_addr, q->buf_len, access);
+ q->umem = ib_umem_get_va(&dev->ibdev, q->buf_addr, q->buf_len, access);
if (IS_ERR(q->umem)) {
- DP_ERR(dev, "create user queue: failed ib_umem_get, got %ld\n",
+ DP_ERR(dev, "create user queue: failed ib_umem_get_va, got %ld\n",
PTR_ERR(q->umem));
return PTR_ERR(q->umem);
}
@@ -1471,13 +1471,14 @@ static int qedr_init_srq_user_params(struct ib_udata *udata,
if (rc)
return rc;
- srq->prod_umem = ib_umem_get(srq->ibsrq.device, ureq->prod_pair_addr,
- sizeof(struct rdma_srq_producers), access);
+ srq->prod_umem = ib_umem_get_va(srq->ibsrq.device, ureq->prod_pair_addr,
+ sizeof(struct rdma_srq_producers),
+ access);
if (IS_ERR(srq->prod_umem)) {
qedr_free_pbl(srq->dev, &srq->usrq.pbl_info, srq->usrq.pbl_tbl);
ib_umem_release(srq->usrq.umem);
DP_ERR(srq->dev,
- "create srq: failed ib_umem_get for producer, got %ld\n",
+ "create srq: failed ib_umem_get_va for producer, got %ld\n",
PTR_ERR(srq->prod_umem));
return PTR_ERR(srq->prod_umem);
}
@@ -2964,7 +2965,7 @@ struct ib_mr *qedr_reg_user_mr(struct ib_pd *ibpd, u64 start, u64 len,
mr->type = QEDR_MR_USER;
- mr->umem = ib_umem_get(ibpd->device, start, len, acc);
+ mr->umem = ib_umem_get_va(ibpd->device, start, len, acc);
if (IS_ERR(mr->umem)) {
rc = -EFAULT;
goto err0;
diff --git a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_cq.c b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_cq.c
index bc3adcc1ae67..5712d40d7211 100644
--- a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_cq.c
+++ b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_cq.c
@@ -138,8 +138,8 @@ int pvrdma_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr,
if (ret)
goto err_cq;
- cq->umem = ib_umem_get(ibdev, ucmd.buf_addr, ucmd.buf_size,
- IB_ACCESS_LOCAL_WRITE);
+ cq->umem = ib_umem_get_va(ibdev, ucmd.buf_addr, ucmd.buf_size,
+ IB_ACCESS_LOCAL_WRITE);
if (IS_ERR(cq->umem)) {
ret = PTR_ERR(cq->umem);
goto err_cq;
diff --git a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_mr.c b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_mr.c
index 05a6bd991502..942381ab0367 100644
--- a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_mr.c
+++ b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_mr.c
@@ -131,7 +131,7 @@ struct ib_mr *pvrdma_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
return ERR_PTR(-EINVAL);
}
- umem = ib_umem_get(pd->device, start, length, access_flags);
+ umem = ib_umem_get_va(pd->device, start, length, access_flags);
if (IS_ERR(umem)) {
dev_warn(&dev->pdev->dev,
"could not get umem for mem region\n");
diff --git a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_qp.c b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_qp.c
index 16aab967a203..5689bf51a7ef 100644
--- a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_qp.c
+++ b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_qp.c
@@ -268,9 +268,9 @@ int pvrdma_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *init_attr,
if (!is_srq) {
/* set qp->sq.wqe_cnt, shift, buf_size.. */
- qp->rumem = ib_umem_get(ibqp->device,
- ucmd.rbuf_addr,
- ucmd.rbuf_size, 0);
+ qp->rumem = ib_umem_get_va(ibqp->device,
+ ucmd.rbuf_addr,
+ ucmd.rbuf_size, 0);
if (IS_ERR(qp->rumem)) {
ret = PTR_ERR(qp->rumem);
goto err_qp;
@@ -281,8 +281,8 @@ int pvrdma_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *init_attr,
qp->srq = to_vsrq(init_attr->srq);
}
- qp->sumem = ib_umem_get(ibqp->device, ucmd.sbuf_addr,
- ucmd.sbuf_size, 0);
+ qp->sumem = ib_umem_get_va(ibqp->device, ucmd.sbuf_addr,
+ ucmd.sbuf_size, 0);
if (IS_ERR(qp->sumem)) {
if (!is_srq)
ib_umem_release(qp->rumem);
diff --git a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_srq.c b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_srq.c
index d31fb692fcaa..fa35a0d73ad0 100644
--- a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_srq.c
+++ b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_srq.c
@@ -146,7 +146,7 @@ int pvrdma_create_srq(struct ib_srq *ibsrq, struct ib_srq_init_attr *init_attr,
if (ret)
goto err_srq;
- srq->umem = ib_umem_get(ibsrq->device, ucmd.buf_addr, ucmd.buf_size, 0);
+ srq->umem = ib_umem_get_va(ibsrq->device, ucmd.buf_addr, ucmd.buf_size, 0);
if (IS_ERR(srq->umem)) {
ret = PTR_ERR(srq->umem);
goto err_srq;
diff --git a/drivers/infiniband/sw/rdmavt/mr.c b/drivers/infiniband/sw/rdmavt/mr.c
index 15f1ff917d6c..3266129e63e7 100644
--- a/drivers/infiniband/sw/rdmavt/mr.c
+++ b/drivers/infiniband/sw/rdmavt/mr.c
@@ -351,7 +351,7 @@ struct ib_mr *rvt_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
if (length == 0)
return ERR_PTR(-EINVAL);
- umem = ib_umem_get(pd->device, start, length, mr_access_flags);
+ umem = ib_umem_get_va(pd->device, start, length, mr_access_flags);
if (IS_ERR(umem))
return ERR_CAST(umem);
diff --git a/drivers/infiniband/sw/rxe/rxe_mr.c b/drivers/infiniband/sw/rxe/rxe_mr.c
index c696ff874980..875eceb55fdf 100644
--- a/drivers/infiniband/sw/rxe/rxe_mr.c
+++ b/drivers/infiniband/sw/rxe/rxe_mr.c
@@ -197,7 +197,7 @@ int rxe_mr_init_user(struct rxe_dev *rxe, u64 start, u64 length,
rxe_mr_init(access, mr);
- umem = ib_umem_get(&rxe->ib_dev, start, length, access);
+ umem = ib_umem_get_va(&rxe->ib_dev, start, length, access);
if (IS_ERR(umem)) {
rxe_dbg_mr(mr, "Unable to pin memory region err = %d\n",
(int)PTR_ERR(umem));
diff --git a/drivers/infiniband/sw/siw/siw_mem.c b/drivers/infiniband/sw/siw/siw_mem.c
index 98c802b3ed72..1677f9246447 100644
--- a/drivers/infiniband/sw/siw/siw_mem.c
+++ b/drivers/infiniband/sw/siw/siw_mem.c
@@ -357,7 +357,7 @@ struct siw_umem *siw_umem_get(struct ib_device *base_dev, u64 start,
rv = -ENOMEM;
goto err_out;
}
- base_mem = ib_umem_get(base_dev, start, len, rights);
+ base_mem = ib_umem_get_va(base_dev, start, len, rights);
if (IS_ERR(base_mem)) {
rv = PTR_ERR(base_mem);
siw_dbg(base_dev, "Cannot pin user memory: %d\n", rv);
diff --git a/include/rdma/ib_umem.h b/include/rdma/ib_umem.h
index 2ad52cc1d52b..25e90766892e 100644
--- a/include/rdma/ib_umem.h
+++ b/include/rdma/ib_umem.h
@@ -75,8 +75,8 @@ static inline size_t ib_umem_num_pages(struct ib_umem *umem)
}
#ifdef CONFIG_INFINIBAND_USER_MEM
-struct ib_umem *ib_umem_get(struct ib_device *device, unsigned long addr,
- size_t size, int access);
+struct ib_umem *ib_umem_get_va(struct ib_device *device, unsigned long addr,
+ size_t size, int access);
void ib_umem_release(struct ib_umem *umem);
int ib_umem_copy_from(void *dst, struct ib_umem *umem, size_t offset,
size_t length);
@@ -160,9 +160,9 @@ void ib_umem_dmabuf_revoke(struct ib_umem_dmabuf *umem_dmabuf);
#include <linux/err.h>
-static inline struct ib_umem *ib_umem_get(struct ib_device *device,
- unsigned long addr, size_t size,
- int access)
+static inline struct ib_umem *ib_umem_get_va(struct ib_device *device,
+ unsigned long addr, size_t size,
+ int access)
{
return ERR_PTR(-EOPNOTSUPP);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH rdma-next v3 02/17] RDMA/umem: Split ib_umem_get_va() into a thin wrapper around __ib_umem_get_va()
2026-05-04 13:57 [PATCH rdma-next v3 00/17] RDMA: Introduce generic buffer descriptor infrastructure for umem Jiri Pirko
2026-05-04 13:57 ` [PATCH rdma-next v3 01/17] RDMA/umem: Rename ib_umem_get() to ib_umem_get_va() Jiri Pirko
@ 2026-05-04 13:57 ` Jiri Pirko
2026-05-04 13:57 ` [PATCH rdma-next v3 03/17] RDMA/core: Introduce generic buffer descriptor infrastructure for umem Jiri Pirko
` (14 subsequent siblings)
16 siblings, 0 replies; 28+ messages in thread
From: Jiri Pirko @ 2026-05-04 13:57 UTC (permalink / raw)
To: linux-rdma
Cc: jgg, leon, mrgolin, gal.pressman, sleybo, parav, mbloch,
yanjun.zhu, marco.crivellari, roman.gushchin, phaddad, lirongqing,
ynachum, huangjunxian6, kalesh-anakkur.purayil, ohartoov,
michaelgur, shayd, edwards, sriharsha.basavapatna,
andrew.gospodarek, selvin.xavier
From: Jiri Pirko <jiri@nvidia.com>
The follow-up patch is going to introduce ib_umem_get_desc(),
the canonical desc-to-umem helper, which needs to pin a userspace VA
without going through the exported ib_umem_get_va() helper so later on
ib_umem_get_va() would use the ib_umem_get_desc() flow too.
Move the existing ib_umem_get_va() to a static __ib_umem_get_va()
and have ib_umem_get_va() as a thin wrapper that calls it.
Signed-off-by: Jiri Pirko <jiri@nvidia.com>
---
v2->v3:
- new patch
---
drivers/infiniband/core/umem.c | 27 +++++++++++++++++----------
1 file changed, 17 insertions(+), 10 deletions(-)
diff --git a/drivers/infiniband/core/umem.c b/drivers/infiniband/core/umem.c
index 986f785a37cd..6e0906f0f5c4 100644
--- a/drivers/infiniband/core/umem.c
+++ b/drivers/infiniband/core/umem.c
@@ -153,16 +153,9 @@ unsigned long ib_umem_find_best_pgsz(struct ib_umem *umem,
}
EXPORT_SYMBOL(ib_umem_find_best_pgsz);
-/**
- * ib_umem_get_va - Pin and DMA map userspace memory.
- *
- * @device: IB device to connect UMEM
- * @addr: userspace virtual address to start at
- * @size: length of region to pin
- * @access: IB_ACCESS_xxx flags for memory being pinned
- */
-struct ib_umem *ib_umem_get_va(struct ib_device *device, unsigned long addr,
- size_t size, int access)
+static struct ib_umem *__ib_umem_get_va(struct ib_device *device,
+ unsigned long addr, size_t size,
+ int access)
{
struct ib_umem *umem;
struct page **page_list;
@@ -278,6 +271,20 @@ struct ib_umem *ib_umem_get_va(struct ib_device *device, unsigned long addr,
}
return ret ? ERR_PTR(ret) : umem;
}
+
+/**
+ * ib_umem_get_va - Pin and DMA map userspace memory.
+ *
+ * @device: IB device to connect UMEM
+ * @addr: userspace virtual address to start at
+ * @size: length of region to pin
+ * @access: IB_ACCESS_xxx flags for memory being pinned
+ */
+struct ib_umem *ib_umem_get_va(struct ib_device *device, unsigned long addr,
+ size_t size, int access)
+{
+ return __ib_umem_get_va(device, addr, size, access);
+}
EXPORT_SYMBOL(ib_umem_get_va);
/**
--
2.53.0
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH rdma-next v3 03/17] RDMA/core: Introduce generic buffer descriptor infrastructure for umem
2026-05-04 13:57 [PATCH rdma-next v3 00/17] RDMA: Introduce generic buffer descriptor infrastructure for umem Jiri Pirko
2026-05-04 13:57 ` [PATCH rdma-next v3 01/17] RDMA/umem: Rename ib_umem_get() to ib_umem_get_va() Jiri Pirko
2026-05-04 13:57 ` [PATCH rdma-next v3 02/17] RDMA/umem: Split ib_umem_get_va() into a thin wrapper around __ib_umem_get_va() Jiri Pirko
@ 2026-05-04 13:57 ` Jiri Pirko
2026-05-06 13:37 ` Jason Gunthorpe
2026-05-04 13:57 ` [PATCH rdma-next v3 04/17] RDMA/umem: Route ib_umem_get_va() through ib_umem_get() Jiri Pirko
` (13 subsequent siblings)
16 siblings, 1 reply; 28+ messages in thread
From: Jiri Pirko @ 2026-05-04 13:57 UTC (permalink / raw)
To: linux-rdma
Cc: jgg, leon, mrgolin, gal.pressman, sleybo, parav, mbloch,
yanjun.zhu, marco.crivellari, roman.gushchin, phaddad, lirongqing,
ynachum, huangjunxian6, kalesh-anakkur.purayil, ohartoov,
michaelgur, shayd, edwards, sriharsha.basavapatna,
andrew.gospodarek, selvin.xavier
From: Jiri Pirko <jiri@nvidia.com>
Introduce a per-attribute UVERBS_ATTR_UMEM model so each uverbs
command's umem set is explicit in its UAPI definition. Add
driver-facing wrapper helpers that pin a umem on demand from an
attribute or a VA addr; the driver owns the returned umem and
releases it from its destroy/error paths.
Signed-off-by: Jiri Pirko <jiri@nvidia.com>
---
v2->v3:
- pushed out desc processing to ib_umem_get_desc()
- replaced UVERBS_ATTR_BUFFERS array with per-attribute UVERBS_ATTR_UMEM
- struct ib_uverbs_buffer_desc: dropped .index, moved .type first,
bumped reserved to __u32 reserved[2]
- added canonical ib_umem_get() + two inline wrappers
(_attr, _attr_or_va)
- dropped ib_umem_list_* family + ib_umem_release_non_listed()
---
drivers/infiniband/core/umem.c | 105 ++++++++++++++++++++++++
include/rdma/ib_umem.h | 55 +++++++++++++
include/rdma/uverbs_ioctl.h | 12 +++
include/uapi/rdma/ib_user_ioctl_verbs.h | 23 ++++++
4 files changed, 195 insertions(+)
diff --git a/drivers/infiniband/core/umem.c b/drivers/infiniband/core/umem.c
index 6e0906f0f5c4..d9073b1012bc 100644
--- a/drivers/infiniband/core/umem.c
+++ b/drivers/infiniband/core/umem.c
@@ -272,6 +272,111 @@ static struct ib_umem *__ib_umem_get_va(struct ib_device *device,
return ret ? ERR_PTR(ret) : umem;
}
+static struct ib_umem *
+ib_umem_get_desc(struct ib_device *device,
+ const struct ib_uverbs_buffer_desc *desc, int access)
+{
+ struct ib_umem_dmabuf *umem_dmabuf;
+
+ if (desc->reserved[0] || desc->reserved[1])
+ return ERR_PTR(-EINVAL);
+
+ switch (desc->type) {
+ case IB_UVERBS_BUFFER_TYPE_DMABUF:
+ umem_dmabuf = ib_umem_dmabuf_get_pinned(device, desc->addr,
+ desc->length, desc->fd,
+ access);
+ if (IS_ERR(umem_dmabuf))
+ return ERR_CAST(umem_dmabuf);
+ return &umem_dmabuf->umem;
+ case IB_UVERBS_BUFFER_TYPE_VA:
+ return __ib_umem_get_va(device, desc->addr, desc->length,
+ access);
+ default:
+ return ERR_PTR(-EINVAL);
+ }
+}
+
+/**
+ * ib_umem_get - Canonical on-demand umem getter.
+ * @device: IB device.
+ * @udata: uverbs udata bundle (may be NULL).
+ * @attr_id: per-command UMEM attribute id; consulted if @udata is set.
+ * @legacy_filler: optional command-specific legacy attr filler.
+ * invoked if @udata is set.
+ * @va_fallback: if true, build a VA-typed desc with @addr.
+ * @addr: user VA, used if @va_fallback is true.
+ * @size: driver-required minimum length.
+ * @access: IB access flags forwarded to ib_umem_get_desc().
+ *
+ * Return: valid umem on success, ERR_PTR(...) on error, NULL
+ * if no source produced a buffer (only possible when @va_fallback is false).
+ */
+struct ib_umem *ib_umem_get(struct ib_device *device, struct ib_udata *udata,
+ u16 attr_id,
+ ib_umem_buf_desc_filler_t legacy_filler,
+ bool va_fallback, u64 addr, size_t size, int access)
+{
+ struct uverbs_attr_bundle *attrs = NULL;
+ struct ib_uverbs_buffer_desc desc = {};
+ bool have_desc = false;
+ struct ib_umem *umem;
+ int ret;
+
+ if (udata)
+ attrs = container_of(udata, struct uverbs_attr_bundle,
+ driver_udata);
+
+ if (attrs) {
+ ret = uverbs_copy_from(&desc, attrs, attr_id);
+ if (!ret)
+ have_desc = true;
+ else if (ret != -ENOENT)
+ return ERR_PTR(ret);
+ }
+
+ if (attrs && legacy_filler) {
+ struct ib_uverbs_buffer_desc legacy_desc = {};
+
+ ret = legacy_filler(attrs, &legacy_desc);
+ if (!ret) {
+ if (have_desc) {
+ ibdev_err(device,
+ "UMEM attr (id=%u) and legacy attrs are mutually exclusive\n",
+ attr_id);
+ return ERR_PTR(-EINVAL);
+ }
+ memcpy(&desc, &legacy_desc, sizeof(desc));
+ have_desc = true;
+ } else if (ret != -ENODATA) {
+ return ERR_PTR(ret);
+ }
+ }
+
+ if (have_desc)
+ goto have_desc;
+
+ if (!va_fallback)
+ return NULL;
+
+ desc = (struct ib_uverbs_buffer_desc){
+ .type = IB_UVERBS_BUFFER_TYPE_VA,
+ .addr = addr,
+ .length = size,
+ };
+
+have_desc:
+ umem = ib_umem_get_desc(device, &desc, access);
+ if (IS_ERR(umem))
+ return umem;
+ if (umem->length < size) {
+ ib_umem_release(umem);
+ return ERR_PTR(-EINVAL);
+ }
+ return umem;
+}
+EXPORT_SYMBOL(ib_umem_get);
+
/**
* ib_umem_get_va - Pin and DMA map userspace memory.
*
diff --git a/include/rdma/ib_umem.h b/include/rdma/ib_umem.h
index 25e90766892e..4897c7599fa3 100644
--- a/include/rdma/ib_umem.h
+++ b/include/rdma/ib_umem.h
@@ -73,10 +73,44 @@ static inline size_t ib_umem_num_pages(struct ib_umem *umem)
{
return ib_umem_num_dma_blocks(umem, PAGE_SIZE);
}
+
+struct ib_udata;
+struct ib_uverbs_buffer_desc;
+struct uverbs_attr_bundle;
+
+/*
+ * Per-command legacy buffer-desc filler.
+ * Returns 0 on success (desc filled), -ENODATA if no legacy attrs apply,
+ * negative errno on validation failure.
+ */
+typedef int (*ib_umem_buf_desc_filler_t)(struct uverbs_attr_bundle *attrs,
+ struct ib_uverbs_buffer_desc *desc);
+
#ifdef CONFIG_INFINIBAND_USER_MEM
+struct ib_umem *ib_umem_get(struct ib_device *device, struct ib_udata *udata,
+ u16 attr_id,
+ ib_umem_buf_desc_filler_t legacy_filler,
+ bool va_fallback, u64 addr, size_t size, int access);
struct ib_umem *ib_umem_get_va(struct ib_device *device, unsigned long addr,
size_t size, int access);
+
+static inline struct ib_umem *
+ib_umem_get_attr(struct ib_device *device, struct ib_udata *udata,
+ u16 attr_id, size_t size, int access)
+{
+ return ib_umem_get(device, udata, attr_id, NULL,
+ false, 0, size, access);
+}
+
+static inline struct ib_umem *
+ib_umem_get_attr_or_va(struct ib_device *device, struct ib_udata *udata,
+ u16 attr_id, u64 addr, size_t size, int access)
+{
+ return ib_umem_get(device, udata, attr_id, NULL,
+ true, addr, size, access);
+}
+
void ib_umem_release(struct ib_umem *umem);
int ib_umem_copy_from(void *dst, struct ib_umem *umem, size_t offset,
size_t length);
@@ -160,12 +194,33 @@ void ib_umem_dmabuf_revoke(struct ib_umem_dmabuf *umem_dmabuf);
#include <linux/err.h>
+static inline struct ib_umem *
+ib_umem_get(struct ib_device *device, struct ib_udata *udata, u16 attr_id,
+ ib_umem_buf_desc_filler_t legacy_filler, bool va_fallback, u64 addr,
+ size_t size, int access)
+{
+ return ERR_PTR(-EOPNOTSUPP);
+}
static inline struct ib_umem *ib_umem_get_va(struct ib_device *device,
unsigned long addr, size_t size,
int access)
{
return ERR_PTR(-EOPNOTSUPP);
}
+static inline struct ib_umem *ib_umem_get_attr(struct ib_device *device,
+ struct ib_udata *udata,
+ u16 attr_id, size_t size,
+ int access)
+{
+ return ERR_PTR(-EOPNOTSUPP);
+}
+static inline struct ib_umem *ib_umem_get_attr_or_va(struct ib_device *device,
+ struct ib_udata *udata,
+ u16 attr_id, u64 addr,
+ size_t size, int access)
+{
+ return ERR_PTR(-EOPNOTSUPP);
+}
static inline void ib_umem_release(struct ib_umem *umem) { }
static inline int ib_umem_copy_from(void *dst, struct ib_umem *umem, size_t offset,
size_t length) {
diff --git a/include/rdma/uverbs_ioctl.h b/include/rdma/uverbs_ioctl.h
index e2af17da3e32..76e94ede668e 100644
--- a/include/rdma/uverbs_ioctl.h
+++ b/include/rdma/uverbs_ioctl.h
@@ -590,6 +590,18 @@ struct uapi_definition {
UA_OPTIONAL, \
.is_udata = 1)
+/*
+ * Per-attribute UMEM descriptor. The payload is a single
+ * struct ib_uverbs_buffer_desc identifying a memory region backed by
+ * dma-buf or user virtual address. _access selects UA_OPTIONAL or
+ * UA_MANDATORY. Drivers obtain a umem from the attribute via the
+ * ib_umem_get_*() wrapper helpers.
+ */
+#define UVERBS_ATTR_UMEM(_attr_id, _access) \
+ UVERBS_ATTR_PTR_IN(_attr_id, \
+ UVERBS_ATTR_TYPE(struct ib_uverbs_buffer_desc), \
+ _access)
+
/* =================================================
* Parsing infrastructure
* =================================================
diff --git a/include/uapi/rdma/ib_user_ioctl_verbs.h b/include/uapi/rdma/ib_user_ioctl_verbs.h
index 90c5cd8e7753..6dfb95d56770 100644
--- a/include/uapi/rdma/ib_user_ioctl_verbs.h
+++ b/include/uapi/rdma/ib_user_ioctl_verbs.h
@@ -273,4 +273,27 @@ struct ib_uverbs_gid_entry {
__u32 netdev_ifindex; /* It is 0 if there is no netdev associated with it */
};
+enum ib_uverbs_buffer_type {
+ IB_UVERBS_BUFFER_TYPE_DMABUF,
+ IB_UVERBS_BUFFER_TYPE_VA,
+};
+
+/*
+ * Describes a single buffer backed by dma-buf or user virtual address.
+ * Used as the payload of a per-attribute UVERBS_ATTR_UMEM-typed attribute.
+ *
+ * @type: buffer type from enum ib_uverbs_buffer_type
+ * @fd: dma-buf file descriptor (valid for IB_UVERBS_BUFFER_TYPE_DMABUF)
+ * @reserved: must be zero
+ * @addr: offset within dma-buf, or user virtual address for VA
+ * @length: buffer length in bytes
+ */
+struct ib_uverbs_buffer_desc {
+ __u32 type;
+ __s32 fd;
+ __u32 reserved[2];
+ __aligned_u64 addr;
+ __aligned_u64 length;
+};
+
#endif
--
2.53.0
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH rdma-next v3 04/17] RDMA/umem: Route ib_umem_get_va() through ib_umem_get()
2026-05-04 13:57 [PATCH rdma-next v3 00/17] RDMA: Introduce generic buffer descriptor infrastructure for umem Jiri Pirko
` (2 preceding siblings ...)
2026-05-04 13:57 ` [PATCH rdma-next v3 03/17] RDMA/core: Introduce generic buffer descriptor infrastructure for umem Jiri Pirko
@ 2026-05-04 13:57 ` Jiri Pirko
2026-05-04 13:57 ` [PATCH rdma-next v3 05/17] RDMA/uverbs: Inline _uverbs_get_const_{signed,unsigned}() Jiri Pirko
` (12 subsequent siblings)
16 siblings, 0 replies; 28+ messages in thread
From: Jiri Pirko @ 2026-05-04 13:57 UTC (permalink / raw)
To: linux-rdma
Cc: jgg, leon, mrgolin, gal.pressman, sleybo, parav, mbloch,
yanjun.zhu, marco.crivellari, roman.gushchin, phaddad, lirongqing,
ynachum, huangjunxian6, kalesh-anakkur.purayil, ohartoov,
michaelgur, shayd, edwards, sriharsha.basavapatna,
andrew.gospodarek, selvin.xavier
From: Jiri Pirko <jiri@nvidia.com>
ib_umem_get_va() is now redundant: ib_umem_get() with va_fallback=true
covers the same path. Make it a static inline wrapper instead of a
separately exported symbol.
Signed-off-by: Jiri Pirko <jiri@nvidia.com>
---
v2->v3:
- new patch
---
drivers/infiniband/core/umem.c | 15 ---------------
include/rdma/ib_umem.h | 9 +++++++--
2 files changed, 7 insertions(+), 17 deletions(-)
diff --git a/drivers/infiniband/core/umem.c b/drivers/infiniband/core/umem.c
index d9073b1012bc..b0ab4133d47d 100644
--- a/drivers/infiniband/core/umem.c
+++ b/drivers/infiniband/core/umem.c
@@ -377,21 +377,6 @@ struct ib_umem *ib_umem_get(struct ib_device *device, struct ib_udata *udata,
}
EXPORT_SYMBOL(ib_umem_get);
-/**
- * ib_umem_get_va - Pin and DMA map userspace memory.
- *
- * @device: IB device to connect UMEM
- * @addr: userspace virtual address to start at
- * @size: length of region to pin
- * @access: IB_ACCESS_xxx flags for memory being pinned
- */
-struct ib_umem *ib_umem_get_va(struct ib_device *device, unsigned long addr,
- size_t size, int access)
-{
- return __ib_umem_get_va(device, addr, size, access);
-}
-EXPORT_SYMBOL(ib_umem_get_va);
-
/**
* ib_umem_release - release pinned memory
* @umem: umem struct to release
diff --git a/include/rdma/ib_umem.h b/include/rdma/ib_umem.h
index 4897c7599fa3..fd45162eb017 100644
--- a/include/rdma/ib_umem.h
+++ b/include/rdma/ib_umem.h
@@ -92,8 +92,13 @@ struct ib_umem *ib_umem_get(struct ib_device *device, struct ib_udata *udata,
u16 attr_id,
ib_umem_buf_desc_filler_t legacy_filler,
bool va_fallback, u64 addr, size_t size, int access);
-struct ib_umem *ib_umem_get_va(struct ib_device *device, unsigned long addr,
- size_t size, int access);
+
+static inline struct ib_umem *ib_umem_get_va(struct ib_device *device,
+ unsigned long addr, size_t size,
+ int access)
+{
+ return ib_umem_get(device, NULL, 0, NULL, true, addr, size, access);
+}
static inline struct ib_umem *
ib_umem_get_attr(struct ib_device *device, struct ib_udata *udata,
--
2.53.0
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH rdma-next v3 05/17] RDMA/uverbs: Inline _uverbs_get_const_{signed,unsigned}()
2026-05-04 13:57 [PATCH rdma-next v3 00/17] RDMA: Introduce generic buffer descriptor infrastructure for umem Jiri Pirko
` (3 preceding siblings ...)
2026-05-04 13:57 ` [PATCH rdma-next v3 04/17] RDMA/umem: Route ib_umem_get_va() through ib_umem_get() Jiri Pirko
@ 2026-05-04 13:57 ` Jiri Pirko
2026-05-04 13:57 ` [PATCH rdma-next v3 06/17] RDMA/uverbs: Push out CQ buffer umem processing into a helper Jiri Pirko
` (11 subsequent siblings)
16 siblings, 0 replies; 28+ messages in thread
From: Jiri Pirko @ 2026-05-04 13:57 UTC (permalink / raw)
To: linux-rdma
Cc: jgg, leon, mrgolin, gal.pressman, sleybo, parav, mbloch,
yanjun.zhu, marco.crivellari, roman.gushchin, phaddad, lirongqing,
ynachum, huangjunxian6, kalesh-anakkur.purayil, ohartoov,
michaelgur, shayd, edwards, sriharsha.basavapatna,
andrew.gospodarek, selvin.xavier
From: Jiri Pirko <jiri@nvidia.com>
uverbs_get_raw_fd() and the related const helpers expand to
out-of-line _uverbs_get_const_{signed,unsigned}() exported
from ib_uverbs. Callers outside of drivers (for example the
about to be introduced CQ buffer-desc filler in ib_core's umem.c)
therefore cannot use them without unnecessary extra dependency.
Both functions are short and only call already-inline
accessors. Move them into the header and drop the two
now-redundant exports, making uverbs_get_raw_fd() and the
related const helpers header-only and usable from anywhere
that includes <rdma/uverbs_ioctl.h>.
Signed-off-by: Jiri Pirko <jiri@nvidia.com>
---
v2->v3:
- new patch
---
drivers/infiniband/core/uverbs_ioctl.c | 47 ------------------------
include/rdma/uverbs_ioctl.h | 51 ++++++++++++++++++++++----
2 files changed, 44 insertions(+), 54 deletions(-)
diff --git a/drivers/infiniband/core/uverbs_ioctl.c b/drivers/infiniband/core/uverbs_ioctl.c
index b61af625e679..a2182d3401da 100644
--- a/drivers/infiniband/core/uverbs_ioctl.c
+++ b/drivers/infiniband/core/uverbs_ioctl.c
@@ -785,53 +785,6 @@ int uverbs_output_written(const struct uverbs_attr_bundle *bundle, size_t idx)
return uverbs_set_output(bundle, attr);
}
-int _uverbs_get_const_signed(s64 *to,
- const struct uverbs_attr_bundle *attrs_bundle,
- size_t idx, s64 lower_bound, u64 upper_bound,
- s64 *def_val)
-{
- const struct uverbs_attr *attr;
-
- attr = uverbs_attr_get(attrs_bundle, idx);
- if (IS_ERR(attr)) {
- if ((PTR_ERR(attr) != -ENOENT) || !def_val)
- return PTR_ERR(attr);
-
- *to = *def_val;
- } else {
- *to = attr->ptr_attr.data;
- }
-
- if (*to < lower_bound || (*to > 0 && (u64)*to > upper_bound))
- return -EINVAL;
-
- return 0;
-}
-EXPORT_SYMBOL(_uverbs_get_const_signed);
-
-int _uverbs_get_const_unsigned(u64 *to,
- const struct uverbs_attr_bundle *attrs_bundle,
- size_t idx, u64 upper_bound, u64 *def_val)
-{
- const struct uverbs_attr *attr;
-
- attr = uverbs_attr_get(attrs_bundle, idx);
- if (IS_ERR(attr)) {
- if ((PTR_ERR(attr) != -ENOENT) || !def_val)
- return PTR_ERR(attr);
-
- *to = *def_val;
- } else {
- *to = attr->ptr_attr.data;
- }
-
- if (*to > upper_bound)
- return -EINVAL;
-
- return 0;
-}
-EXPORT_SYMBOL(_uverbs_get_const_unsigned);
-
int uverbs_copy_to_struct_or_zero(const struct uverbs_attr_bundle *bundle,
size_t idx, const void *from, size_t size)
{
diff --git a/include/rdma/uverbs_ioctl.h b/include/rdma/uverbs_ioctl.h
index 76e94ede668e..70caa7299dbf 100644
--- a/include/rdma/uverbs_ioctl.h
+++ b/include/rdma/uverbs_ioctl.h
@@ -900,13 +900,50 @@ static inline __malloc void *uverbs_kcalloc(struct uverbs_attr_bundle *bundle,
return uverbs_zalloc(bundle, bytes);
}
-int _uverbs_get_const_signed(s64 *to,
- const struct uverbs_attr_bundle *attrs_bundle,
- size_t idx, s64 lower_bound, u64 upper_bound,
- s64 *def_val);
-int _uverbs_get_const_unsigned(u64 *to,
- const struct uverbs_attr_bundle *attrs_bundle,
- size_t idx, u64 upper_bound, u64 *def_val);
+static inline int
+_uverbs_get_const_signed(s64 *to,
+ const struct uverbs_attr_bundle *attrs_bundle,
+ size_t idx, s64 lower_bound, u64 upper_bound,
+ s64 *def_val)
+{
+ const struct uverbs_attr *attr;
+
+ attr = uverbs_attr_get(attrs_bundle, idx);
+ if (IS_ERR(attr)) {
+ if ((PTR_ERR(attr) != -ENOENT) || !def_val)
+ return PTR_ERR(attr);
+ *to = *def_val;
+ } else {
+ *to = attr->ptr_attr.data;
+ }
+
+ if (*to < lower_bound || (*to > 0 && (u64)*to > upper_bound))
+ return -EINVAL;
+
+ return 0;
+}
+
+static inline int
+_uverbs_get_const_unsigned(u64 *to,
+ const struct uverbs_attr_bundle *attrs_bundle,
+ size_t idx, u64 upper_bound, u64 *def_val)
+{
+ const struct uverbs_attr *attr;
+
+ attr = uverbs_attr_get(attrs_bundle, idx);
+ if (IS_ERR(attr)) {
+ if ((PTR_ERR(attr) != -ENOENT) || !def_val)
+ return PTR_ERR(attr);
+ *to = *def_val;
+ } else {
+ *to = attr->ptr_attr.data;
+ }
+
+ if (*to > upper_bound)
+ return -EINVAL;
+
+ return 0;
+}
int uverbs_copy_to_struct_or_zero(const struct uverbs_attr_bundle *bundle,
size_t idx, const void *from, size_t size);
--
2.53.0
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH rdma-next v3 06/17] RDMA/uverbs: Push out CQ buffer umem processing into a helper
2026-05-04 13:57 [PATCH rdma-next v3 00/17] RDMA: Introduce generic buffer descriptor infrastructure for umem Jiri Pirko
` (4 preceding siblings ...)
2026-05-04 13:57 ` [PATCH rdma-next v3 05/17] RDMA/uverbs: Inline _uverbs_get_const_{signed,unsigned}() Jiri Pirko
@ 2026-05-04 13:57 ` Jiri Pirko
2026-05-04 13:57 ` [PATCH rdma-next v3 07/17] RDMA/uverbs: Add CQ buffer UMEM attribute and driver helpers Jiri Pirko
` (10 subsequent siblings)
16 siblings, 0 replies; 28+ messages in thread
From: Jiri Pirko @ 2026-05-04 13:57 UTC (permalink / raw)
To: linux-rdma
Cc: jgg, leon, mrgolin, gal.pressman, sleybo, parav, mbloch,
yanjun.zhu, marco.crivellari, roman.gushchin, phaddad, lirongqing,
ynachum, huangjunxian6, kalesh-anakkur.purayil, ohartoov,
michaelgur, shayd, edwards, sriharsha.basavapatna,
andrew.gospodarek, selvin.xavier
From: Jiri Pirko <jiri@nvidia.com>
Extract the UVERBS_ATTR_CREATE_CQ_BUFFER_* parser from the CQ
create handler into uverbs_create_cq_get_buffer_desc(), and wrap
it in ib_umem_get_cq_tmp(), the umem-producing helper the cq_create
handler now calls.
ib_umem_get_cq_tmp() is temporary; subsequent patches replace it
with driver-owned ib_umem_get_cq_buf*() wrappers built on the
same parser, and remove it once all CQ drivers have switched.
Signed-off-by: Jiri Pirko <jiri@nvidia.com>
---
v2->v3:
- renamed uverbs_create_cq_get_umem() to ib_umem_get_cq_tmp() and
moved to umem.c
- split legacy attr parser into uverbs_create_cq_get_buffer_desc()
for upcoming ib_umem_get_cq_buf*() reuse
- rebased on top of "RDMA/core: Fix user CQ creation for drivers
without create_cq"
---
drivers/infiniband/core/umem.c | 79 +++++++++++++++++++
drivers/infiniband/core/uverbs_std_types_cq.c | 60 +-------------
include/rdma/ib_umem.h | 7 ++
3 files changed, 89 insertions(+), 57 deletions(-)
diff --git a/drivers/infiniband/core/umem.c b/drivers/infiniband/core/umem.c
index b0ab4133d47d..f720de8cb162 100644
--- a/drivers/infiniband/core/umem.c
+++ b/drivers/infiniband/core/umem.c
@@ -377,6 +377,85 @@ struct ib_umem *ib_umem_get(struct ib_device *device, struct ib_udata *udata,
}
EXPORT_SYMBOL(ib_umem_get);
+static int uverbs_create_cq_get_buffer_desc(struct uverbs_attr_bundle *attrs,
+ struct ib_uverbs_buffer_desc *desc)
+{
+ struct ib_device *ib_dev = attrs->context->device;
+ int ret;
+
+ if (uverbs_attr_is_valid(attrs, UVERBS_ATTR_CREATE_CQ_BUFFER_VA)) {
+ ret = uverbs_copy_from(&desc->addr, attrs,
+ UVERBS_ATTR_CREATE_CQ_BUFFER_VA);
+ if (ret)
+ return ret;
+ ret = uverbs_copy_from(&desc->length, attrs,
+ UVERBS_ATTR_CREATE_CQ_BUFFER_LENGTH);
+ if (ret)
+ return ret;
+ if (uverbs_attr_is_valid(attrs, UVERBS_ATTR_CREATE_CQ_BUFFER_FD) ||
+ uverbs_attr_is_valid(attrs, UVERBS_ATTR_CREATE_CQ_BUFFER_OFFSET) ||
+ !ib_dev->ops.create_user_cq)
+ return -EINVAL;
+ desc->type = IB_UVERBS_BUFFER_TYPE_VA;
+ return 0;
+ }
+
+ if (uverbs_attr_is_valid(attrs, UVERBS_ATTR_CREATE_CQ_BUFFER_FD)) {
+ ret = uverbs_get_raw_fd(&desc->fd, attrs,
+ UVERBS_ATTR_CREATE_CQ_BUFFER_FD);
+ if (ret)
+ return ret;
+
+ ret = uverbs_copy_from(&desc->addr, attrs,
+ UVERBS_ATTR_CREATE_CQ_BUFFER_OFFSET);
+ if (ret)
+ return ret;
+ ret = uverbs_copy_from(&desc->length, attrs,
+ UVERBS_ATTR_CREATE_CQ_BUFFER_LENGTH);
+ if (ret)
+ return ret;
+ if (uverbs_attr_is_valid(attrs, UVERBS_ATTR_CREATE_CQ_BUFFER_VA) ||
+ !ib_dev->ops.create_user_cq)
+ return -EINVAL;
+ desc->type = IB_UVERBS_BUFFER_TYPE_DMABUF;
+ return 0;
+ }
+
+ if (uverbs_attr_is_valid(attrs, UVERBS_ATTR_CREATE_CQ_BUFFER_OFFSET) ||
+ uverbs_attr_is_valid(attrs, UVERBS_ATTR_CREATE_CQ_BUFFER_LENGTH))
+ return -EINVAL;
+ return -ENODATA;
+}
+
+/**
+ * ib_umem_get_cq_tmp - Temporary CQ buffer umem getter.
+ * @device: IB device.
+ * @attrs: uverbs attribute bundle.
+ *
+ * Pins a CQ buffer described by the legacy CQ buffer attributes.
+ * Returns NULL when none are supplied.
+ *
+ * Will be removed once all CQ drivers have switched to get
+ * their buffer directly.
+ *
+ * Return: caller-owned umem on success; NULL when no legacy attribute
+ * is supplied; ERR_PTR(...) on error.
+ */
+struct ib_umem *ib_umem_get_cq_tmp(struct ib_device *device,
+ struct uverbs_attr_bundle *attrs)
+{
+ struct ib_uverbs_buffer_desc desc = {};
+ int ret;
+
+ ret = uverbs_create_cq_get_buffer_desc(attrs, &desc);
+ if (ret == -ENODATA)
+ return NULL;
+ if (ret)
+ return ERR_PTR(ret);
+ return ib_umem_get_desc(device, &desc, IB_ACCESS_LOCAL_WRITE);
+}
+EXPORT_SYMBOL(ib_umem_get_cq_tmp);
+
/**
* ib_umem_release - release pinned memory
* @umem: umem struct to release
diff --git a/drivers/infiniband/core/uverbs_std_types_cq.c b/drivers/infiniband/core/uverbs_std_types_cq.c
index 1a6bc8baa52b..711bad0aa8a3 100644
--- a/drivers/infiniband/core/uverbs_std_types_cq.c
+++ b/drivers/infiniband/core/uverbs_std_types_cq.c
@@ -66,16 +66,11 @@ static int UVERBS_HANDLER(UVERBS_METHOD_CQ_CREATE)(
typeof(*obj), uevent.uobject);
struct ib_uverbs_completion_event_file *ev_file = NULL;
struct ib_device *ib_dev = attrs->context->device;
- struct ib_umem_dmabuf *umem_dmabuf;
struct ib_cq_init_attr attr = {};
struct ib_uobject *ev_file_uobj;
struct ib_umem *umem = NULL;
- u64 buffer_length;
- u64 buffer_offset;
struct ib_cq *cq;
u64 user_handle;
- u64 buffer_va;
- int buffer_fd;
int ret;
if ((!ib_dev->ops.create_cq && !ib_dev->ops.create_user_cq) ||
@@ -122,58 +117,9 @@ static int UVERBS_HANDLER(UVERBS_METHOD_CQ_CREATE)(
INIT_LIST_HEAD(&obj->comp_list);
INIT_LIST_HEAD(&obj->uevent.event_list);
- if (uverbs_attr_is_valid(attrs, UVERBS_ATTR_CREATE_CQ_BUFFER_VA)) {
-
- ret = uverbs_copy_from(&buffer_va, attrs, UVERBS_ATTR_CREATE_CQ_BUFFER_VA);
- if (ret)
- goto err_event_file;
-
- ret = uverbs_copy_from(&buffer_length, attrs, UVERBS_ATTR_CREATE_CQ_BUFFER_LENGTH);
- if (ret)
- goto err_event_file;
-
- if (uverbs_attr_is_valid(attrs, UVERBS_ATTR_CREATE_CQ_BUFFER_FD) ||
- uverbs_attr_is_valid(attrs, UVERBS_ATTR_CREATE_CQ_BUFFER_OFFSET) ||
- !ib_dev->ops.create_user_cq) {
- ret = -EINVAL;
- goto err_event_file;
- }
-
- umem = ib_umem_get_va(ib_dev, buffer_va, buffer_length, IB_ACCESS_LOCAL_WRITE);
- if (IS_ERR(umem)) {
- ret = PTR_ERR(umem);
- goto err_event_file;
- }
- } else if (uverbs_attr_is_valid(attrs, UVERBS_ATTR_CREATE_CQ_BUFFER_FD)) {
-
- ret = uverbs_get_raw_fd(&buffer_fd, attrs, UVERBS_ATTR_CREATE_CQ_BUFFER_FD);
- if (ret)
- goto err_event_file;
-
- ret = uverbs_copy_from(&buffer_offset, attrs, UVERBS_ATTR_CREATE_CQ_BUFFER_OFFSET);
- if (ret)
- goto err_event_file;
-
- ret = uverbs_copy_from(&buffer_length, attrs, UVERBS_ATTR_CREATE_CQ_BUFFER_LENGTH);
- if (ret)
- goto err_event_file;
-
- if (uverbs_attr_is_valid(attrs, UVERBS_ATTR_CREATE_CQ_BUFFER_VA) ||
- !ib_dev->ops.create_user_cq) {
- ret = -EINVAL;
- goto err_event_file;
- }
-
- umem_dmabuf = ib_umem_dmabuf_get_pinned(ib_dev, buffer_offset, buffer_length,
- buffer_fd, IB_ACCESS_LOCAL_WRITE);
- if (IS_ERR(umem_dmabuf)) {
- ret = PTR_ERR(umem_dmabuf);
- goto err_event_file;
- }
- umem = &umem_dmabuf->umem;
- } else if (uverbs_attr_is_valid(attrs, UVERBS_ATTR_CREATE_CQ_BUFFER_OFFSET) ||
- uverbs_attr_is_valid(attrs, UVERBS_ATTR_CREATE_CQ_BUFFER_LENGTH)) {
- ret = -EINVAL;
+ umem = ib_umem_get_cq_tmp(ib_dev, attrs);
+ if (IS_ERR(umem)) {
+ ret = PTR_ERR(umem);
goto err_event_file;
}
diff --git a/include/rdma/ib_umem.h b/include/rdma/ib_umem.h
index fd45162eb017..afe12a1bedb0 100644
--- a/include/rdma/ib_umem.h
+++ b/include/rdma/ib_umem.h
@@ -92,6 +92,8 @@ struct ib_umem *ib_umem_get(struct ib_device *device, struct ib_udata *udata,
u16 attr_id,
ib_umem_buf_desc_filler_t legacy_filler,
bool va_fallback, u64 addr, size_t size, int access);
+struct ib_umem *ib_umem_get_cq_tmp(struct ib_device *device,
+ struct uverbs_attr_bundle *attrs);
static inline struct ib_umem *ib_umem_get_va(struct ib_device *device,
unsigned long addr, size_t size,
@@ -206,6 +208,11 @@ ib_umem_get(struct ib_device *device, struct ib_udata *udata, u16 attr_id,
{
return ERR_PTR(-EOPNOTSUPP);
}
+static inline struct ib_umem *
+ib_umem_get_cq_tmp(struct ib_device *device, struct uverbs_attr_bundle *attrs)
+{
+ return ERR_PTR(-EOPNOTSUPP);
+}
static inline struct ib_umem *ib_umem_get_va(struct ib_device *device,
unsigned long addr, size_t size,
int access)
--
2.53.0
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH rdma-next v3 07/17] RDMA/uverbs: Add CQ buffer UMEM attribute and driver helpers
2026-05-04 13:57 [PATCH rdma-next v3 00/17] RDMA: Introduce generic buffer descriptor infrastructure for umem Jiri Pirko
` (5 preceding siblings ...)
2026-05-04 13:57 ` [PATCH rdma-next v3 06/17] RDMA/uverbs: Push out CQ buffer umem processing into a helper Jiri Pirko
@ 2026-05-04 13:57 ` Jiri Pirko
2026-05-06 13:46 ` Jason Gunthorpe
2026-05-04 13:57 ` [PATCH rdma-next v3 08/17] RDMA/efa: Use ib_umem_get_cq_buf() for user CQ buffer Jiri Pirko
` (9 subsequent siblings)
16 siblings, 1 reply; 28+ messages in thread
From: Jiri Pirko @ 2026-05-04 13:57 UTC (permalink / raw)
To: linux-rdma
Cc: jgg, leon, mrgolin, gal.pressman, sleybo, parav, mbloch,
yanjun.zhu, marco.crivellari, roman.gushchin, phaddad, lirongqing,
ynachum, huangjunxian6, kalesh-anakkur.purayil, ohartoov,
michaelgur, shayd, edwards, sriharsha.basavapatna,
andrew.gospodarek, selvin.xavier
From: Jiri Pirko <jiri@nvidia.com>
Add UVERBS_ATTR_CREATE_CQ_BUF_UMEM and two driver-facing
wrappers, ib_umem_get_cq_buf() and ib_umem_get_cq_buf_or_va(),
that pin a CQ buffer umem from it. The wrappers reuse the
existing legacy CQ buffer-attr filler.
Signed-off-by: Jiri Pirko <jiri@nvidia.com>
---
v2->v3:
- new patch
---
drivers/infiniband/core/umem.c | 48 +++++++++++++++++++
drivers/infiniband/core/uverbs_std_types_cq.c | 2 +
include/rdma/ib_umem.h | 19 ++++++++
include/uapi/rdma/ib_user_ioctl_cmds.h | 1 +
4 files changed, 70 insertions(+)
diff --git a/drivers/infiniband/core/umem.c b/drivers/infiniband/core/umem.c
index f720de8cb162..04684411c82e 100644
--- a/drivers/infiniband/core/umem.c
+++ b/drivers/infiniband/core/umem.c
@@ -427,6 +427,54 @@ static int uverbs_create_cq_get_buffer_desc(struct uverbs_attr_bundle *attrs,
return -ENODATA;
}
+/**
+ * ib_umem_get_cq_buf - Pin a CQ buffer umem from per-command attributes.
+ * @device: IB device.
+ * @udata: uverbs udata bundle (may be NULL).
+ * @size: minimum required CQ buffer length.
+ * @access: IB access flags.
+ *
+ * Resolves the CQ buffer from the new UMEM attribute or the legacy
+ * CQ buffer attributes. There is no UHW VA fallback, so the caller
+ * must arrange its own backing (typically an in-kernel allocation)
+ * when no source is available.
+ *
+ * Return: caller-owned umem on success; NULL when no source supplied
+ * a buffer; ERR_PTR(...) on error.
+ */
+struct ib_umem *ib_umem_get_cq_buf(struct ib_device *device,
+ struct ib_udata *udata, size_t size,
+ int access)
+{
+ return ib_umem_get(device, udata, UVERBS_ATTR_CREATE_CQ_BUF_UMEM,
+ uverbs_create_cq_get_buffer_desc, false, 0,
+ size, access);
+}
+EXPORT_SYMBOL(ib_umem_get_cq_buf);
+
+/**
+ * ib_umem_get_cq_buf_or_va - Pin a CQ buffer umem with UHW VA fallback.
+ * @device: IB device.
+ * @udata: uverbs udata bundle (may be NULL).
+ * @addr: UHW user VA used when no per-command attribute matched.
+ * @size: minimum required CQ buffer length.
+ * @access: IB access flags.
+ *
+ * Like ib_umem_get_cq_buf(), but pins @addr/@size when neither the
+ * UMEM attribute nor the legacy CQ buffer attributes are supplied.
+ *
+ * Return: caller-owned umem on success, ERR_PTR(...) on error.
+ */
+struct ib_umem *ib_umem_get_cq_buf_or_va(struct ib_device *device,
+ struct ib_udata *udata, u64 addr,
+ size_t size, int access)
+{
+ return ib_umem_get(device, udata, UVERBS_ATTR_CREATE_CQ_BUF_UMEM,
+ uverbs_create_cq_get_buffer_desc, true, addr,
+ size, access);
+}
+EXPORT_SYMBOL(ib_umem_get_cq_buf_or_va);
+
/**
* ib_umem_get_cq_tmp - Temporary CQ buffer umem getter.
* @device: IB device.
diff --git a/drivers/infiniband/core/uverbs_std_types_cq.c b/drivers/infiniband/core/uverbs_std_types_cq.c
index 711bad0aa8a3..05d1294762c0 100644
--- a/drivers/infiniband/core/uverbs_std_types_cq.c
+++ b/drivers/infiniband/core/uverbs_std_types_cq.c
@@ -215,6 +215,8 @@ DECLARE_UVERBS_NAMED_METHOD(
UVERBS_ATTR_PTR_IN(UVERBS_ATTR_CREATE_CQ_BUFFER_OFFSET,
UVERBS_ATTR_TYPE(u64),
UA_OPTIONAL),
+ UVERBS_ATTR_UMEM(UVERBS_ATTR_CREATE_CQ_BUF_UMEM,
+ UA_OPTIONAL),
UVERBS_ATTR_UHW());
static int UVERBS_HANDLER(UVERBS_METHOD_CQ_DESTROY)(
diff --git a/include/rdma/ib_umem.h b/include/rdma/ib_umem.h
index afe12a1bedb0..174788a0640d 100644
--- a/include/rdma/ib_umem.h
+++ b/include/rdma/ib_umem.h
@@ -92,6 +92,12 @@ struct ib_umem *ib_umem_get(struct ib_device *device, struct ib_udata *udata,
u16 attr_id,
ib_umem_buf_desc_filler_t legacy_filler,
bool va_fallback, u64 addr, size_t size, int access);
+struct ib_umem *ib_umem_get_cq_buf(struct ib_device *device,
+ struct ib_udata *udata, size_t size,
+ int access);
+struct ib_umem *ib_umem_get_cq_buf_or_va(struct ib_device *device,
+ struct ib_udata *udata, u64 addr,
+ size_t size, int access);
struct ib_umem *ib_umem_get_cq_tmp(struct ib_device *device,
struct uverbs_attr_bundle *attrs);
@@ -208,6 +214,19 @@ ib_umem_get(struct ib_device *device, struct ib_udata *udata, u16 attr_id,
{
return ERR_PTR(-EOPNOTSUPP);
}
+static inline struct ib_umem *ib_umem_get_cq_buf(struct ib_device *device,
+ struct ib_udata *udata,
+ size_t size, int access)
+{
+ return ERR_PTR(-EOPNOTSUPP);
+}
+static inline struct ib_umem *ib_umem_get_cq_buf_or_va(struct ib_device *device,
+ struct ib_udata *udata,
+ u64 addr, size_t size,
+ int access)
+{
+ return ERR_PTR(-EOPNOTSUPP);
+}
static inline struct ib_umem *
ib_umem_get_cq_tmp(struct ib_device *device, struct uverbs_attr_bundle *attrs)
{
diff --git a/include/uapi/rdma/ib_user_ioctl_cmds.h b/include/uapi/rdma/ib_user_ioctl_cmds.h
index 72041c1b0ea5..02835b7fd76d 100644
--- a/include/uapi/rdma/ib_user_ioctl_cmds.h
+++ b/include/uapi/rdma/ib_user_ioctl_cmds.h
@@ -117,6 +117,7 @@ enum uverbs_attrs_create_cq_cmd_attr_ids {
UVERBS_ATTR_CREATE_CQ_BUFFER_LENGTH,
UVERBS_ATTR_CREATE_CQ_BUFFER_FD,
UVERBS_ATTR_CREATE_CQ_BUFFER_OFFSET,
+ UVERBS_ATTR_CREATE_CQ_BUF_UMEM,
};
enum uverbs_attrs_destroy_cq_cmd_attr_ids {
--
2.53.0
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH rdma-next v3 08/17] RDMA/efa: Use ib_umem_get_cq_buf() for user CQ buffer
2026-05-04 13:57 [PATCH rdma-next v3 00/17] RDMA: Introduce generic buffer descriptor infrastructure for umem Jiri Pirko
` (6 preceding siblings ...)
2026-05-04 13:57 ` [PATCH rdma-next v3 07/17] RDMA/uverbs: Add CQ buffer UMEM attribute and driver helpers Jiri Pirko
@ 2026-05-04 13:57 ` Jiri Pirko
2026-05-06 13:51 ` Jason Gunthorpe
2026-05-04 13:57 ` [PATCH rdma-next v3 09/17] RDMA/mlx5: Use ib_umem_get_cq_buf_or_va() " Jiri Pirko
` (8 subsequent siblings)
16 siblings, 1 reply; 28+ messages in thread
From: Jiri Pirko @ 2026-05-04 13:57 UTC (permalink / raw)
To: linux-rdma
Cc: jgg, leon, mrgolin, gal.pressman, sleybo, parav, mbloch,
yanjun.zhu, marco.crivellari, roman.gushchin, phaddad, lirongqing,
ynachum, huangjunxian6, kalesh-anakkur.purayil, ohartoov,
michaelgur, shayd, edwards, sriharsha.basavapatna,
andrew.gospodarek, selvin.xavier
From: Jiri Pirko <jiri@nvidia.com>
Pin the user CQ buffer with ib_umem_get_cq_buf() and take
ownership of the umem in the driver. Fall back to the
existing kernel-DMA path on NULL.
Signed-off-by: Jiri Pirko <jiri@nvidia.com>
---
v2->v3:
- used ib_umem_get_cq_buf() to get umem, stored in efa_cq->umem
- replaced ib_umem_release_non_listed() with ib_umem_release()
- added release to efa_destroy_cq() and new error path
---
drivers/infiniband/hw/efa/efa_verbs.c | 27 +++++++++++++++++----------
1 file changed, 17 insertions(+), 10 deletions(-)
diff --git a/drivers/infiniband/hw/efa/efa_verbs.c b/drivers/infiniband/hw/efa/efa_verbs.c
index e103d1654a69..aebae70b882c 100644
--- a/drivers/infiniband/hw/efa/efa_verbs.c
+++ b/drivers/infiniband/hw/efa/efa_verbs.c
@@ -1072,6 +1072,7 @@ int efa_destroy_cq(struct ib_cq *ibcq, struct ib_udata *udata)
if (cq->cpu_addr)
efa_free_mapped(dev, cq->cpu_addr, cq->dma_addr, cq->size, DMA_FROM_DEVICE);
+ ib_umem_release(cq->umem);
return 0;
}
@@ -1124,6 +1125,7 @@ int efa_create_user_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr,
struct efa_ibv_create_cq cmd;
struct efa_cq *cq = to_ecq(ibcq);
int entries = attr->cqe;
+ struct ib_umem *umem;
bool set_src_addr;
int err;
@@ -1172,26 +1174,29 @@ int efa_create_user_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr,
cq->ucontext = ucontext;
cq->size = PAGE_ALIGN(cmd.cq_entry_size * entries * cmd.num_sub_cqs);
- if (ibcq->umem) {
- if (ibcq->umem->length < cq->size) {
- ibdev_dbg(&dev->ibdev, "External memory too small\n");
- err = -EINVAL;
- goto err_out;
- }
+ umem = ib_umem_get_cq_buf(ibcq->device, udata, cq->size,
+ IB_ACCESS_LOCAL_WRITE);
+ if (IS_ERR(umem)) {
+ err = PTR_ERR(umem);
+ goto err_out;
+ }
+
+ cq->umem = umem;
- if (!ib_umem_is_contiguous(ibcq->umem)) {
+ if (umem) {
+ if (!ib_umem_is_contiguous(umem)) {
ibdev_dbg(&dev->ibdev, "Non contiguous CQ unsupported\n");
err = -EINVAL;
- goto err_out;
+ goto err_release_umem;
}
- cq->dma_addr = ib_umem_start_dma_addr(ibcq->umem);
+ cq->dma_addr = ib_umem_start_dma_addr(umem);
} else {
cq->cpu_addr = efa_zalloc_mapped(dev, &cq->dma_addr, cq->size,
DMA_FROM_DEVICE);
if (!cq->cpu_addr) {
err = -ENOMEM;
- goto err_out;
+ goto err_release_umem;
}
}
@@ -1262,6 +1267,8 @@ int efa_create_user_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr,
if (cq->cpu_addr)
efa_free_mapped(dev, cq->cpu_addr, cq->dma_addr, cq->size,
DMA_FROM_DEVICE);
+err_release_umem:
+ ib_umem_release(cq->umem);
err_out:
atomic64_inc(&dev->stats.create_cq_err);
return err;
--
2.53.0
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH rdma-next v3 09/17] RDMA/mlx5: Use ib_umem_get_cq_buf_or_va() for user CQ buffer
2026-05-04 13:57 [PATCH rdma-next v3 00/17] RDMA: Introduce generic buffer descriptor infrastructure for umem Jiri Pirko
` (7 preceding siblings ...)
2026-05-04 13:57 ` [PATCH rdma-next v3 08/17] RDMA/efa: Use ib_umem_get_cq_buf() for user CQ buffer Jiri Pirko
@ 2026-05-04 13:57 ` Jiri Pirko
2026-05-04 13:57 ` [PATCH rdma-next v3 10/17] RDMA/bnxt_re: " Jiri Pirko
` (7 subsequent siblings)
16 siblings, 0 replies; 28+ messages in thread
From: Jiri Pirko @ 2026-05-04 13:57 UTC (permalink / raw)
To: linux-rdma
Cc: jgg, leon, mrgolin, gal.pressman, sleybo, parav, mbloch,
yanjun.zhu, marco.crivellari, roman.gushchin, phaddad, lirongqing,
ynachum, huangjunxian6, kalesh-anakkur.purayil, ohartoov,
michaelgur, shayd, edwards, sriharsha.basavapatna,
andrew.gospodarek, selvin.xavier
From: Jiri Pirko <jiri@nvidia.com>
Pin the user CQ buffer with ib_umem_get_cq_buf_or_va() and take
ownership of the umem in the driver. Apply the same ownership
pattern to the resize path.
Signed-off-by: Jiri Pirko <jiri@nvidia.com>
---
v2->v3:
- used ib_umem_get_cq_buf_or_va() to get umem, stored in cq->buf.umem
- replaced ib_umem_release_non_listed() with ib_umem_release()
- added release to destroy_cq_user() and the resize error path
---
drivers/infiniband/hw/mlx5/cq.c | 27 ++++++++++++++-------------
1 file changed, 14 insertions(+), 13 deletions(-)
diff --git a/drivers/infiniband/hw/mlx5/cq.c b/drivers/infiniband/hw/mlx5/cq.c
index b8a4a69c5686..fb6172a9be57 100644
--- a/drivers/infiniband/hw/mlx5/cq.c
+++ b/drivers/infiniband/hw/mlx5/cq.c
@@ -745,15 +745,15 @@ static int create_cq_user(struct mlx5_ib_dev *dev, struct ib_udata *udata,
*cqe_size = ucmd.cqe_size;
- if (!cq->ibcq.umem)
- cq->ibcq.umem = ib_umem_get_va(&dev->ib_dev, ucmd.buf_addr,
- entries * ucmd.cqe_size,
- IB_ACCESS_LOCAL_WRITE);
- if (IS_ERR(cq->ibcq.umem))
- return PTR_ERR(cq->ibcq.umem);
+ cq->buf.umem = ib_umem_get_cq_buf_or_va(&dev->ib_dev, udata,
+ ucmd.buf_addr,
+ entries * ucmd.cqe_size,
+ IB_ACCESS_LOCAL_WRITE);
+ if (IS_ERR(cq->buf.umem))
+ return PTR_ERR(cq->buf.umem);
page_size = mlx5_umem_find_best_cq_quantized_pgoff(
- cq->ibcq.umem, cqc, log_page_size, MLX5_ADAPTER_PAGE_SHIFT,
+ cq->buf.umem, cqc, log_page_size, MLX5_ADAPTER_PAGE_SHIFT,
page_offset, 64, &page_offset_quantized);
if (!page_size) {
err = -EINVAL;
@@ -764,12 +764,12 @@ static int create_cq_user(struct mlx5_ib_dev *dev, struct ib_udata *udata,
if (err)
goto err_umem;
- ncont = ib_umem_num_dma_blocks(cq->ibcq.umem, page_size);
+ ncont = ib_umem_num_dma_blocks(cq->buf.umem, page_size);
mlx5_ib_dbg(
dev,
"addr 0x%llx, size %u, npages %zu, page_size %lu, ncont %d\n",
ucmd.buf_addr, entries * ucmd.cqe_size,
- ib_umem_num_pages(cq->ibcq.umem), page_size, ncont);
+ ib_umem_num_pages(cq->buf.umem), page_size, ncont);
*inlen = MLX5_ST_SZ_BYTES(create_cq_in) +
MLX5_FLD_SZ_BYTES(create_cq_in, pas[0]) * ncont;
@@ -780,7 +780,7 @@ static int create_cq_user(struct mlx5_ib_dev *dev, struct ib_udata *udata,
}
pas = (__be64 *)MLX5_ADDR_OF(create_cq_in, *cqb, pas);
- mlx5_ib_populate_pas(cq->ibcq.umem, page_size, pas, 0);
+ mlx5_ib_populate_pas(cq->buf.umem, page_size, pas, 0);
cqc = MLX5_ADDR_OF(create_cq_in, *cqb, cq_context);
MLX5_SET(cqc, cqc, log_page_size,
@@ -853,7 +853,7 @@ static int create_cq_user(struct mlx5_ib_dev *dev, struct ib_udata *udata,
mlx5_ib_db_unmap_user(context, &cq->db);
err_umem:
- /* UMEM is released by ib_core */
+ ib_umem_release(cq->buf.umem);
return err;
}
@@ -863,6 +863,7 @@ static void destroy_cq_user(struct mlx5_ib_cq *cq, struct ib_udata *udata)
udata, struct mlx5_ib_ucontext, ibucontext);
mlx5_ib_db_unmap_user(context, &cq->db);
+ ib_umem_release(cq->buf.umem);
}
static void init_cq_frag_buf(struct mlx5_ib_cq_buf *buf)
@@ -1434,8 +1435,8 @@ int mlx5_ib_resize_cq(struct ib_cq *ibcq, unsigned int entries,
if (udata) {
cq->ibcq.cqe = entries - 1;
- ib_umem_release(cq->ibcq.umem);
- cq->ibcq.umem = cq->resize_umem;
+ ib_umem_release(cq->buf.umem);
+ cq->buf.umem = cq->resize_umem;
cq->resize_umem = NULL;
} else {
struct mlx5_ib_cq_buf tbuf;
--
2.53.0
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH rdma-next v3 10/17] RDMA/bnxt_re: Use ib_umem_get_cq_buf_or_va() for user CQ buffer
2026-05-04 13:57 [PATCH rdma-next v3 00/17] RDMA: Introduce generic buffer descriptor infrastructure for umem Jiri Pirko
` (8 preceding siblings ...)
2026-05-04 13:57 ` [PATCH rdma-next v3 09/17] RDMA/mlx5: Use ib_umem_get_cq_buf_or_va() " Jiri Pirko
@ 2026-05-04 13:57 ` Jiri Pirko
2026-05-04 13:57 ` [PATCH rdma-next v3 11/17] RDMA/mlx4: Use ib_umem_get_cq_buf() " Jiri Pirko
` (6 subsequent siblings)
16 siblings, 0 replies; 28+ messages in thread
From: Jiri Pirko @ 2026-05-04 13:57 UTC (permalink / raw)
To: linux-rdma
Cc: jgg, leon, mrgolin, gal.pressman, sleybo, parav, mbloch,
yanjun.zhu, marco.crivellari, roman.gushchin, phaddad, lirongqing,
ynachum, huangjunxian6, kalesh-anakkur.purayil, ohartoov,
michaelgur, shayd, edwards, sriharsha.basavapatna,
andrew.gospodarek, selvin.xavier
From: Jiri Pirko <jiri@nvidia.com>
Pin the user CQ buffer with ib_umem_get_cq_buf_or_va() and take
ownership of the umem in the driver. Apply the same ownership
pattern to the resize path.
Signed-off-by: Jiri Pirko <jiri@nvidia.com>
---
v2->v3:
- used ib_umem_get_cq_buf_or_va() to get umem, stored in new
struct bnxt_re_cq field cq->umem
- replaced ib_umem_release_non_listed() with ib_umem_release()
- added release to bnxt_re_destroy_cq() and the resize error path
---
drivers/infiniband/hw/bnxt_re/ib_verbs.c | 35 +++++++++++++-----------
drivers/infiniband/hw/bnxt_re/ib_verbs.h | 1 +
2 files changed, 20 insertions(+), 16 deletions(-)
diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.c b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
index 1f626b7c6af2..fa7da02b3704 100644
--- a/drivers/infiniband/hw/bnxt_re/ib_verbs.c
+++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
@@ -3342,6 +3342,7 @@ int bnxt_re_destroy_cq(struct ib_cq *ib_cq, struct ib_udata *udata)
atomic_dec(&rdev->stats.res.cq_count);
kfree(cq->cql);
+ ib_umem_release(cq->umem);
return ib_respond_empty_udata(udata);
}
@@ -3402,17 +3403,15 @@ int bnxt_re_create_user_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *att
entries = bnxt_re_init_depth(attr->cqe + 1,
dev_attr->max_cq_wqes + 1, uctx);
- if (!ibcq->umem) {
- ibcq->umem = ib_umem_get_va(&rdev->ibdev, req.cq_va,
+ cq->umem = ib_umem_get_cq_buf_or_va(&rdev->ibdev, udata, req.cq_va,
entries * sizeof(struct cq_base),
IB_ACCESS_LOCAL_WRITE);
- if (IS_ERR(ibcq->umem))
- return PTR_ERR(ibcq->umem);
- }
+ if (IS_ERR(cq->umem))
+ return PTR_ERR(cq->umem);
- rc = bnxt_re_setup_sginfo(rdev, ibcq->umem, &cq->qplib_cq.sg_info);
+ rc = bnxt_re_setup_sginfo(rdev, cq->umem, &cq->qplib_cq.sg_info);
if (rc)
- return rc;
+ goto free_umem;
cq->qplib_cq.dpi = &uctx->dpi;
cq->qplib_cq.max_wqe = entries;
@@ -3422,7 +3421,7 @@ int bnxt_re_create_user_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *att
rc = bnxt_qplib_create_cq(&rdev->qplib_res, &cq->qplib_cq);
if (rc)
- return rc;
+ goto free_umem;
cq->ib_cq.cqe = entries;
cq->cq_period = cq->qplib_cq.period;
@@ -3435,8 +3434,10 @@ int bnxt_re_create_user_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *att
hash_add(rdev->cq_hash, &cq->hash_entry, cq->qplib_cq.id);
/* Allocate a page */
cq->uctx_cq_page = (void *)get_zeroed_page(GFP_KERNEL);
- if (!cq->uctx_cq_page)
- return -ENOMEM;
+ if (!cq->uctx_cq_page) {
+ rc = -ENOMEM;
+ goto destroy_cq;
+ }
resp.comp_mask |= BNXT_RE_CQ_TOGGLE_PAGE_SUPPORT;
}
@@ -3444,15 +3445,17 @@ int bnxt_re_create_user_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *att
resp.tail = cq->qplib_cq.hwq.cons;
resp.phase = cq->qplib_cq.period;
rc = ib_respond_udata(udata, resp);
- if (rc) {
- bnxt_qplib_destroy_cq(&rdev->qplib_res, &cq->qplib_cq);
+ if (rc)
goto free_mem;
- }
return 0;
free_mem:
free_page((unsigned long)cq->uctx_cq_page);
+destroy_cq:
+ bnxt_qplib_destroy_cq(&rdev->qplib_res, &cq->qplib_cq);
+free_umem:
+ ib_umem_release(cq->umem);
return rc;
}
@@ -3516,8 +3519,8 @@ static void bnxt_re_resize_cq_complete(struct bnxt_re_cq *cq)
cq->qplib_cq.max_wqe = cq->resize_cqe;
if (cq->resize_umem) {
- ib_umem_release(cq->ib_cq.umem);
- cq->ib_cq.umem = cq->resize_umem;
+ ib_umem_release(cq->umem);
+ cq->umem = cq->resize_umem;
cq->resize_umem = NULL;
cq->resize_cqe = 0;
}
@@ -4113,7 +4116,7 @@ int bnxt_re_poll_cq(struct ib_cq *ib_cq, int num_entries, struct ib_wc *wc)
/* User CQ; the only processing we do is to
* complete any pending CQ resize operation.
*/
- if (cq->ib_cq.umem) {
+ if (cq->umem) {
if (cq->resize_umem)
bnxt_re_resize_cq_complete(cq);
return 0;
diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.h b/drivers/infiniband/hw/bnxt_re/ib_verbs.h
index 08f71a94d55d..af50e769b1b1 100644
--- a/drivers/infiniband/hw/bnxt_re/ib_verbs.h
+++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.h
@@ -108,6 +108,7 @@ struct bnxt_re_cq {
struct bnxt_qplib_cqe *cql;
#define MAX_CQL_PER_POLL 1024
u32 max_cql;
+ struct ib_umem *umem;
struct ib_umem *resize_umem;
int resize_cqe;
void *uctx_cq_page;
--
2.53.0
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH rdma-next v3 11/17] RDMA/mlx4: Use ib_umem_get_cq_buf() for user CQ buffer
2026-05-04 13:57 [PATCH rdma-next v3 00/17] RDMA: Introduce generic buffer descriptor infrastructure for umem Jiri Pirko
` (9 preceding siblings ...)
2026-05-04 13:57 ` [PATCH rdma-next v3 10/17] RDMA/bnxt_re: " Jiri Pirko
@ 2026-05-04 13:57 ` Jiri Pirko
2026-05-04 13:57 ` [PATCH rdma-next v3 12/17] RDMA/uverbs: Remove legacy umem field from struct ib_cq Jiri Pirko
` (5 subsequent siblings)
16 siblings, 0 replies; 28+ messages in thread
From: Jiri Pirko @ 2026-05-04 13:57 UTC (permalink / raw)
To: linux-rdma
Cc: jgg, leon, mrgolin, gal.pressman, sleybo, parav, mbloch,
yanjun.zhu, marco.crivellari, roman.gushchin, phaddad, lirongqing,
ynachum, huangjunxian6, kalesh-anakkur.purayil, ohartoov,
michaelgur, shayd, edwards, sriharsha.basavapatna,
andrew.gospodarek, selvin.xavier
From: Jiri Pirko <jiri@nvidia.com>
Pin the user CQ buffer with ib_umem_get_cq_buf() and take
ownership of the umem in the driver; fall back to
ib_umem_get_va() for the legacy UHW VA path. Apply the same
ownership pattern to the resize path.
Signed-off-by: Jiri Pirko <jiri@nvidia.com>
---
v2->v3:
- used ib_umem_get_cq_buf() to get umem, with ib_umem_get_va()
as the legacy UHW VA fallback; stored in new struct mlx4_ib_cq
field cq->umem
- replaced ib_umem_release_non_listed() with ib_umem_release()
- added release to mlx4_ib_destroy_cq(), the create error path
and the resize error path
v1->v2:
- rebase on top of Leon's fix
---
drivers/infiniband/hw/mlx4/cq.c | 50 +++++++++++++++++-----------
drivers/infiniband/hw/mlx4/mlx4_ib.h | 1 +
2 files changed, 31 insertions(+), 20 deletions(-)
diff --git a/drivers/infiniband/hw/mlx4/cq.c b/drivers/infiniband/hw/mlx4/cq.c
index 381c7dfa4667..86557b413ca5 100644
--- a/drivers/infiniband/hw/mlx4/cq.c
+++ b/drivers/infiniband/hw/mlx4/cq.c
@@ -172,32 +172,40 @@ int mlx4_ib_create_user_cq(struct ib_cq *ibcq,
if (err)
goto err_cq;
- if (ibcq->umem &&
- (dev->dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_SW_CQ_INIT))
- return -EOPNOTSUPP;
-
- buf_addr = (void *)(unsigned long)ucmd.buf_addr;
-
- if (!ibcq->umem)
- ibcq->umem = ib_umem_get_va(&dev->ib_dev, ucmd.buf_addr,
- entries * cqe_size,
- IB_ACCESS_LOCAL_WRITE);
- if (IS_ERR(ibcq->umem)) {
- err = PTR_ERR(ibcq->umem);
+ cq->umem = ib_umem_get_cq_buf(&dev->ib_dev, udata, entries * cqe_size,
+ IB_ACCESS_LOCAL_WRITE);
+ if (IS_ERR(cq->umem)) {
+ err = PTR_ERR(cq->umem);
goto err_cq;
}
+ if (cq->umem) {
+ if (dev->dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_SW_CQ_INIT) {
+ err = -EOPNOTSUPP;
+ goto err_umem;
+ }
+ } else {
+ cq->umem = ib_umem_get_va(&dev->ib_dev, ucmd.buf_addr,
+ entries * cqe_size,
+ IB_ACCESS_LOCAL_WRITE);
+ if (IS_ERR(cq->umem)) {
+ err = PTR_ERR(cq->umem);
+ goto err_cq;
+ }
+ }
- shift = mlx4_ib_umem_calc_optimal_mtt_size(cq->ibcq.umem, 0, &n);
+ buf_addr = (void *)(unsigned long)ucmd.buf_addr;
+
+ shift = mlx4_ib_umem_calc_optimal_mtt_size(cq->umem, 0, &n);
if (shift < 0) {
err = shift;
- goto err_cq;
+ goto err_umem;
}
err = mlx4_mtt_init(dev->dev, n, shift, &cq->buf.mtt);
if (err)
- goto err_cq;
+ goto err_umem;
- err = mlx4_ib_umem_write_mtt(dev, &cq->buf.mtt, cq->ibcq.umem);
+ err = mlx4_ib_umem_write_mtt(dev, &cq->buf.mtt, cq->umem);
if (err)
goto err_mtt;
@@ -234,7 +242,9 @@ int mlx4_ib_create_user_cq(struct ib_cq *ibcq,
err_mtt:
mlx4_mtt_cleanup(dev->dev, &cq->buf.mtt);
- /* UMEM is released by ib_core */
+
+err_umem:
+ ib_umem_release(cq->umem);
err_cq:
return err;
@@ -471,8 +481,8 @@ int mlx4_ib_resize_cq(struct ib_cq *ibcq, unsigned int entries,
if (ibcq->uobject) {
cq->buf = cq->resize_buf->buf;
cq->ibcq.cqe = cq->resize_buf->cqe;
- ib_umem_release(cq->ibcq.umem);
- cq->ibcq.umem = cq->resize_umem;
+ ib_umem_release(cq->umem);
+ cq->umem = cq->resize_umem;
kfree(cq->resize_buf);
cq->resize_buf = NULL;
@@ -532,7 +542,7 @@ int mlx4_ib_destroy_cq(struct ib_cq *cq, struct ib_udata *udata)
struct mlx4_ib_ucontext,
ibucontext),
&mcq->db);
- /* UMEM is released by ib_core */
+ ib_umem_release(mcq->umem);
} else {
mlx4_ib_free_cq_buf(dev, &mcq->buf, cq->cqe);
mlx4_db_free(dev->dev, &mcq->db);
diff --git a/drivers/infiniband/hw/mlx4/mlx4_ib.h b/drivers/infiniband/hw/mlx4/mlx4_ib.h
index 5a799d6df93e..598954dd0613 100644
--- a/drivers/infiniband/hw/mlx4/mlx4_ib.h
+++ b/drivers/infiniband/hw/mlx4/mlx4_ib.h
@@ -121,6 +121,7 @@ struct mlx4_ib_cq {
struct mlx4_db db;
spinlock_t lock;
struct mutex resize_mutex;
+ struct ib_umem *umem;
struct ib_umem *resize_umem;
/* List of qps that it serves.*/
struct list_head send_qp_list;
--
2.53.0
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH rdma-next v3 12/17] RDMA/uverbs: Remove legacy umem field from struct ib_cq
2026-05-04 13:57 [PATCH rdma-next v3 00/17] RDMA: Introduce generic buffer descriptor infrastructure for umem Jiri Pirko
` (10 preceding siblings ...)
2026-05-04 13:57 ` [PATCH rdma-next v3 11/17] RDMA/mlx4: Use ib_umem_get_cq_buf() " Jiri Pirko
@ 2026-05-04 13:57 ` Jiri Pirko
2026-05-04 13:57 ` [PATCH rdma-next v3 13/17] RDMA/uverbs: Use UMEM attributes for QP creation Jiri Pirko
` (4 subsequent siblings)
16 siblings, 0 replies; 28+ messages in thread
From: Jiri Pirko @ 2026-05-04 13:57 UTC (permalink / raw)
To: linux-rdma
Cc: jgg, leon, mrgolin, gal.pressman, sleybo, parav, mbloch,
yanjun.zhu, marco.crivellari, roman.gushchin, phaddad, lirongqing,
ynachum, huangjunxian6, kalesh-anakkur.purayil, ohartoov,
michaelgur, shayd, edwards, sriharsha.basavapatna,
andrew.gospodarek, selvin.xavier
From: Jiri Pirko <jiri@nvidia.com>
Now that all drivers use helper to get umem and manage the lifetime,
legacy umem field in struct ib_cq is no longer needed. Remove it
along with ib_umem_get_cq_tmp() helper that populated it and both
error and destroy paths.
Signed-off-by: Jiri Pirko <jiri@nvidia.com>
---
v2->v3:
- rebased on top of umem_list removal
---
drivers/infiniband/core/umem.c | 29 -------------------
drivers/infiniband/core/uverbs_cmd.c | 1 -
drivers/infiniband/core/uverbs_std_types_cq.c | 17 -----------
drivers/infiniband/core/verbs.c | 7 -----
include/rdma/ib_umem.h | 7 -----
include/rdma/ib_verbs.h | 1 -
6 files changed, 62 deletions(-)
diff --git a/drivers/infiniband/core/umem.c b/drivers/infiniband/core/umem.c
index 04684411c82e..b1877b83b021 100644
--- a/drivers/infiniband/core/umem.c
+++ b/drivers/infiniband/core/umem.c
@@ -475,35 +475,6 @@ struct ib_umem *ib_umem_get_cq_buf_or_va(struct ib_device *device,
}
EXPORT_SYMBOL(ib_umem_get_cq_buf_or_va);
-/**
- * ib_umem_get_cq_tmp - Temporary CQ buffer umem getter.
- * @device: IB device.
- * @attrs: uverbs attribute bundle.
- *
- * Pins a CQ buffer described by the legacy CQ buffer attributes.
- * Returns NULL when none are supplied.
- *
- * Will be removed once all CQ drivers have switched to get
- * their buffer directly.
- *
- * Return: caller-owned umem on success; NULL when no legacy attribute
- * is supplied; ERR_PTR(...) on error.
- */
-struct ib_umem *ib_umem_get_cq_tmp(struct ib_device *device,
- struct uverbs_attr_bundle *attrs)
-{
- struct ib_uverbs_buffer_desc desc = {};
- int ret;
-
- ret = uverbs_create_cq_get_buffer_desc(attrs, &desc);
- if (ret == -ENODATA)
- return NULL;
- if (ret)
- return ERR_PTR(ret);
- return ib_umem_get_desc(device, &desc, IB_ACCESS_LOCAL_WRITE);
-}
-EXPORT_SYMBOL(ib_umem_get_cq_tmp);
-
/**
* ib_umem_release - release pinned memory
* @umem: umem struct to release
diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c
index 30fa08d12feb..2a70774c639a 100644
--- a/drivers/infiniband/core/uverbs_cmd.c
+++ b/drivers/infiniband/core/uverbs_cmd.c
@@ -1079,7 +1079,6 @@ static int create_cq(struct uverbs_attr_bundle *attrs,
return uverbs_response(attrs, &resp, sizeof(resp));
err_free:
- ib_umem_release(cq->umem);
rdma_restrack_put(&cq->res);
kfree(cq);
err_file:
diff --git a/drivers/infiniband/core/uverbs_std_types_cq.c b/drivers/infiniband/core/uverbs_std_types_cq.c
index 05d1294762c0..148cdd180dab 100644
--- a/drivers/infiniband/core/uverbs_std_types_cq.c
+++ b/drivers/infiniband/core/uverbs_std_types_cq.c
@@ -68,7 +68,6 @@ static int UVERBS_HANDLER(UVERBS_METHOD_CQ_CREATE)(
struct ib_device *ib_dev = attrs->context->device;
struct ib_cq_init_attr attr = {};
struct ib_uobject *ev_file_uobj;
- struct ib_umem *umem = NULL;
struct ib_cq *cq;
u64 user_handle;
int ret;
@@ -117,16 +116,9 @@ static int UVERBS_HANDLER(UVERBS_METHOD_CQ_CREATE)(
INIT_LIST_HEAD(&obj->comp_list);
INIT_LIST_HEAD(&obj->uevent.event_list);
- umem = ib_umem_get_cq_tmp(ib_dev, attrs);
- if (IS_ERR(umem)) {
- ret = PTR_ERR(umem);
- goto err_event_file;
- }
-
cq = rdma_zalloc_drv_obj(ib_dev, ib_cq);
if (!cq) {
ret = -ENOMEM;
- ib_umem_release(umem);
goto err_event_file;
}
@@ -135,11 +127,6 @@ static int UVERBS_HANDLER(UVERBS_METHOD_CQ_CREATE)(
cq->comp_handler = ib_uverbs_comp_handler;
cq->event_handler = ib_uverbs_cq_event_handler;
cq->cq_context = ev_file ? &ev_file->ev_queue : NULL;
- /*
- * If UMEM is not provided here, legacy drivers will set it during
- * CQ creation based on their internal udata.
- */
- cq->umem = umem;
atomic_set(&cq->usecnt, 0);
rdma_restrack_new(&cq->res, RDMA_RESTRACK_CQ);
@@ -152,9 +139,6 @@ static int UVERBS_HANDLER(UVERBS_METHOD_CQ_CREATE)(
if (ret)
goto err_free;
- /* Check that driver didn't overrun existing umem */
- WARN_ON(umem && cq->umem != umem);
-
obj->uevent.uobject.object = cq;
obj->uevent.uobject.user_handle = user_handle;
rdma_restrack_add(&cq->res);
@@ -165,7 +149,6 @@ static int UVERBS_HANDLER(UVERBS_METHOD_CQ_CREATE)(
return ret;
err_free:
- ib_umem_release(cq->umem);
rdma_restrack_put(&cq->res);
kfree(cq);
err_event_file:
diff --git a/drivers/infiniband/core/verbs.c b/drivers/infiniband/core/verbs.c
index bac87de9cc67..de7d19fabd75 100644
--- a/drivers/infiniband/core/verbs.c
+++ b/drivers/infiniband/core/verbs.c
@@ -2221,12 +2221,6 @@ struct ib_cq *__ib_create_cq(struct ib_device *device,
kfree(cq);
return ERR_PTR(ret);
}
- /*
- * We are in kernel verbs flow and drivers are not allowed
- * to set umem pointer, it needs to stay NULL.
- */
- WARN_ON_ONCE(cq->umem);
-
rdma_restrack_add(&cq->res);
return cq;
}
@@ -2257,7 +2251,6 @@ int ib_destroy_cq_user(struct ib_cq *cq, struct ib_udata *udata)
if (ret)
return ret;
- ib_umem_release(cq->umem);
rdma_restrack_del(&cq->res);
kfree(cq);
return ret;
diff --git a/include/rdma/ib_umem.h b/include/rdma/ib_umem.h
index 174788a0640d..e5a0bff2c4bf 100644
--- a/include/rdma/ib_umem.h
+++ b/include/rdma/ib_umem.h
@@ -98,8 +98,6 @@ struct ib_umem *ib_umem_get_cq_buf(struct ib_device *device,
struct ib_umem *ib_umem_get_cq_buf_or_va(struct ib_device *device,
struct ib_udata *udata, u64 addr,
size_t size, int access);
-struct ib_umem *ib_umem_get_cq_tmp(struct ib_device *device,
- struct uverbs_attr_bundle *attrs);
static inline struct ib_umem *ib_umem_get_va(struct ib_device *device,
unsigned long addr, size_t size,
@@ -227,11 +225,6 @@ static inline struct ib_umem *ib_umem_get_cq_buf_or_va(struct ib_device *device,
{
return ERR_PTR(-EOPNOTSUPP);
}
-static inline struct ib_umem *
-ib_umem_get_cq_tmp(struct ib_device *device, struct uverbs_attr_bundle *attrs)
-{
- return ERR_PTR(-EOPNOTSUPP);
-}
static inline struct ib_umem *ib_umem_get_va(struct ib_device *device,
unsigned long addr, size_t size,
int access)
diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h
index b4291ae12922..d06071b87d96 100644
--- a/include/rdma/ib_verbs.h
+++ b/include/rdma/ib_verbs.h
@@ -1739,7 +1739,6 @@ struct ib_cq {
u8 interrupt:1;
u8 shared:1;
unsigned int comp_vector;
- struct ib_umem *umem;
/*
* Implementation details of the RDMA core, don't use in drivers:
--
2.53.0
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH rdma-next v3 13/17] RDMA/uverbs: Use UMEM attributes for QP creation
2026-05-04 13:57 [PATCH rdma-next v3 00/17] RDMA: Introduce generic buffer descriptor infrastructure for umem Jiri Pirko
` (11 preceding siblings ...)
2026-05-04 13:57 ` [PATCH rdma-next v3 12/17] RDMA/uverbs: Remove legacy umem field from struct ib_cq Jiri Pirko
@ 2026-05-04 13:57 ` Jiri Pirko
2026-05-06 13:43 ` Jason Gunthorpe
2026-05-04 13:57 ` [PATCH rdma-next v3 14/17] RDMA/mlx5: Use UMEM attributes for QP buffers in create_qp Jiri Pirko
` (3 subsequent siblings)
16 siblings, 1 reply; 28+ messages in thread
From: Jiri Pirko @ 2026-05-04 13:57 UTC (permalink / raw)
To: linux-rdma
Cc: jgg, leon, mrgolin, gal.pressman, sleybo, parav, mbloch,
yanjun.zhu, marco.crivellari, roman.gushchin, phaddad, lirongqing,
ynachum, huangjunxian6, kalesh-anakkur.purayil, ohartoov,
michaelgur, shayd, edwards, sriharsha.basavapatna,
andrew.gospodarek, selvin.xavier
From: Jiri Pirko <jiri@nvidia.com>
Apply the per-attribute UMEM model to the QP create method. Add
optional UMEM attributes for the whole-QP, RQ, and SQ buffers
that drivers pick from.
Signed-off-by: Jiri Pirko <jiri@nvidia.com>
---
v2->v3:
- replaced the array-form UVERBS_ATTR_BUFFERS attribute and its
uverbs_buf_qp_slots enum with per-attribute UMEM attrs
- dropped qp->umem_list field, handler allocation, write-path NULL
arg, and the umem_list parameter on ib_create_qp_user()
v1->v2:
- fixed umem_list double free
---
drivers/infiniband/core/uverbs_std_types_qp.c | 6 ++++++
include/uapi/rdma/ib_user_ioctl_cmds.h | 3 +++
2 files changed, 9 insertions(+)
diff --git a/drivers/infiniband/core/uverbs_std_types_qp.c b/drivers/infiniband/core/uverbs_std_types_qp.c
index be0730e8509e..e44974abc6b5 100644
--- a/drivers/infiniband/core/uverbs_std_types_qp.c
+++ b/drivers/infiniband/core/uverbs_std_types_qp.c
@@ -340,6 +340,12 @@ DECLARE_UVERBS_NAMED_METHOD(
UVERBS_ATTR_PTR_OUT(UVERBS_ATTR_CREATE_QP_RESP_QP_NUM,
UVERBS_ATTR_TYPE(u32),
UA_MANDATORY),
+ UVERBS_ATTR_UMEM(UVERBS_ATTR_CREATE_QP_BUF_UMEM,
+ UA_OPTIONAL),
+ UVERBS_ATTR_UMEM(UVERBS_ATTR_CREATE_QP_RQ_BUF_UMEM,
+ UA_OPTIONAL),
+ UVERBS_ATTR_UMEM(UVERBS_ATTR_CREATE_QP_SQ_BUF_UMEM,
+ UA_OPTIONAL),
UVERBS_ATTR_UHW());
static int UVERBS_HANDLER(UVERBS_METHOD_QP_DESTROY)(
diff --git a/include/uapi/rdma/ib_user_ioctl_cmds.h b/include/uapi/rdma/ib_user_ioctl_cmds.h
index 02835b7fd76d..839835bd4b23 100644
--- a/include/uapi/rdma/ib_user_ioctl_cmds.h
+++ b/include/uapi/rdma/ib_user_ioctl_cmds.h
@@ -159,6 +159,9 @@ enum uverbs_attrs_create_qp_cmd_attr_ids {
UVERBS_ATTR_CREATE_QP_EVENT_FD,
UVERBS_ATTR_CREATE_QP_RESP_CAP,
UVERBS_ATTR_CREATE_QP_RESP_QP_NUM,
+ UVERBS_ATTR_CREATE_QP_BUF_UMEM,
+ UVERBS_ATTR_CREATE_QP_RQ_BUF_UMEM,
+ UVERBS_ATTR_CREATE_QP_SQ_BUF_UMEM,
};
enum uverbs_attrs_destroy_qp_cmd_attr_ids {
--
2.53.0
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH rdma-next v3 14/17] RDMA/mlx5: Use UMEM attributes for QP buffers in create_qp
2026-05-04 13:57 [PATCH rdma-next v3 00/17] RDMA: Introduce generic buffer descriptor infrastructure for umem Jiri Pirko
` (12 preceding siblings ...)
2026-05-04 13:57 ` [PATCH rdma-next v3 13/17] RDMA/uverbs: Use UMEM attributes for QP creation Jiri Pirko
@ 2026-05-04 13:57 ` Jiri Pirko
2026-05-04 13:57 ` [PATCH rdma-next v3 15/17] RDMA/mlx5: Use UMEM attribute for CQ doorbell record Jiri Pirko
` (2 subsequent siblings)
16 siblings, 0 replies; 28+ messages in thread
From: Jiri Pirko @ 2026-05-04 13:57 UTC (permalink / raw)
To: linux-rdma
Cc: jgg, leon, mrgolin, gal.pressman, sleybo, parav, mbloch,
yanjun.zhu, marco.crivellari, roman.gushchin, phaddad, lirongqing,
ynachum, huangjunxian6, kalesh-anakkur.purayil, ohartoov,
michaelgur, shayd, edwards, sriharsha.basavapatna,
andrew.gospodarek, selvin.xavier
From: Jiri Pirko <jiri@nvidia.com>
Use the per-attribute UMEM helpers to pin QP buffer umems on
demand. The QP-type predicate selects between the BUF and RQ_BUF
attrs; raw-packet SQ uses its own dedicated SQ_BUF attr.
Signed-off-by: Jiri Pirko <jiri@nvidia.com>
---
v2->v3:
- changed to use ib_umem_get_attr_or_va() per-attr
- added ubuffer->umem / sq->ubuffer.umem to store umem
- renamed mlx5_qp_buf_slot() -> mlx5_qp_buf_attr()
- replaced ib_umem_release_non_listed() with ib_umem_release()
---
drivers/infiniband/hw/mlx5/qp.c | 28 +++++++++++++++++++++-------
1 file changed, 21 insertions(+), 7 deletions(-)
diff --git a/drivers/infiniband/hw/mlx5/qp.c b/drivers/infiniband/hw/mlx5/qp.c
index 1bc279d14749..1b764a573dd7 100644
--- a/drivers/infiniband/hw/mlx5/qp.c
+++ b/drivers/infiniband/hw/mlx5/qp.c
@@ -938,6 +938,14 @@ static int adjust_bfregn(struct mlx5_ib_dev *dev,
bfregn % MLX5_NON_FP_BFREGS_PER_UAR;
}
+static u16 mlx5_qp_buf_attr(struct mlx5_ib_qp *qp)
+{
+ if (qp->type == IB_QPT_RAW_PACKET ||
+ qp->flags & IB_QP_CREATE_SOURCE_QPN)
+ return UVERBS_ATTR_CREATE_QP_RQ_BUF_UMEM;
+ return UVERBS_ATTR_CREATE_QP_BUF_UMEM;
+}
+
static int _create_user_qp(struct mlx5_ib_dev *dev, struct ib_pd *pd,
struct mlx5_ib_qp *qp, struct ib_udata *udata,
struct ib_qp_init_attr *attr, u32 **in,
@@ -998,14 +1006,20 @@ static int _create_user_qp(struct mlx5_ib_dev *dev, struct ib_pd *pd,
if (err)
goto err_bfreg;
- if (ucmd->buf_addr && ubuffer->buf_size) {
+ ubuffer->umem = NULL;
+ if (ubuffer->buf_size) {
ubuffer->buf_addr = ucmd->buf_addr;
- ubuffer->umem = ib_umem_get_va(&dev->ib_dev, ubuffer->buf_addr,
- ubuffer->buf_size, 0);
+ ubuffer->umem = ib_umem_get_attr_or_va(&dev->ib_dev, udata,
+ mlx5_qp_buf_attr(qp),
+ ubuffer->buf_addr,
+ ubuffer->buf_size, 0);
if (IS_ERR(ubuffer->umem)) {
err = PTR_ERR(ubuffer->umem);
+ ubuffer->umem = NULL;
goto err_bfreg;
}
+ }
+ if (ubuffer->umem) {
page_size = mlx5_umem_find_best_quantized_pgoff(
ubuffer->umem, qpc, log_page_size,
MLX5_ADAPTER_PAGE_SHIFT, page_offset, 64,
@@ -1015,8 +1029,6 @@ static int _create_user_qp(struct mlx5_ib_dev *dev, struct ib_pd *pd,
goto err_umem;
}
ncont = ib_umem_num_dma_blocks(ubuffer->umem, page_size);
- } else {
- ubuffer->umem = NULL;
}
*inlen = MLX5_ST_SZ_BYTES(create_qp_in) +
@@ -1352,8 +1364,10 @@ static int create_raw_packet_qp_sq(struct mlx5_ib_dev *dev,
if (ts_format < 0)
return ts_format;
- sq->ubuffer.umem = ib_umem_get_va(&dev->ib_dev, ubuffer->buf_addr,
- ubuffer->buf_size, 0);
+ sq->ubuffer.umem = ib_umem_get_attr_or_va(&dev->ib_dev, udata,
+ UVERBS_ATTR_CREATE_QP_SQ_BUF_UMEM,
+ ubuffer->buf_addr,
+ ubuffer->buf_size, 0);
if (IS_ERR(sq->ubuffer.umem))
return PTR_ERR(sq->ubuffer.umem);
page_size = mlx5_umem_find_best_quantized_pgoff(
--
2.53.0
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH rdma-next v3 15/17] RDMA/mlx5: Use UMEM attribute for CQ doorbell record
2026-05-04 13:57 [PATCH rdma-next v3 00/17] RDMA: Introduce generic buffer descriptor infrastructure for umem Jiri Pirko
` (13 preceding siblings ...)
2026-05-04 13:57 ` [PATCH rdma-next v3 14/17] RDMA/mlx5: Use UMEM attributes for QP buffers in create_qp Jiri Pirko
@ 2026-05-04 13:57 ` Jiri Pirko
2026-05-04 13:57 ` [PATCH rdma-next v3 16/17] RDMA/mlx5: Use UMEM attribute for QP " Jiri Pirko
2026-05-04 13:57 ` [PATCH rdma-next v3 17/17] RDMA/uverbs: Track attr consumption and warn on unused attrs Jiri Pirko
16 siblings, 0 replies; 28+ messages in thread
From: Jiri Pirko @ 2026-05-04 13:57 UTC (permalink / raw)
To: linux-rdma
Cc: jgg, leon, mrgolin, gal.pressman, sleybo, parav, mbloch,
yanjun.zhu, marco.crivellari, roman.gushchin, phaddad, lirongqing,
ynachum, huangjunxian6, kalesh-anakkur.purayil, ohartoov,
michaelgur, shayd, edwards, sriharsha.basavapatna,
andrew.gospodarek, selvin.xavier
From: Jiri Pirko <jiri@nvidia.com>
Add an optional mlx5 driver-namespace UMEM attribute on CQ
create so userspace can supply the doorbell record umem
explicitly. Resolve it inside mlx5_ib_db_map_user() and use it
as a private DBR page when present; otherwise take the existing
UHW share-or-pin path that preserves per-page DBR sharing
across CQ/QP/SRQ in the same process.
Signed-off-by: Jiri Pirko <jiri@nvidia.com>
---
v2->v3:
- moved CQ DBR attr to mlx5 driver namespace
- changed to use ib_umem_get_attr() to get umem
- added page-crossing check
---
drivers/infiniband/hw/mlx5/cq.c | 8 +++-
drivers/infiniband/hw/mlx5/doorbell.c | 51 ++++++++++++++++++++----
drivers/infiniband/hw/mlx5/mlx5_ib.h | 5 ++-
drivers/infiniband/hw/mlx5/qp.c | 4 +-
drivers/infiniband/hw/mlx5/srq.c | 2 +-
include/uapi/rdma/mlx5_user_ioctl_cmds.h | 1 +
6 files changed, 57 insertions(+), 14 deletions(-)
diff --git a/drivers/infiniband/hw/mlx5/cq.c b/drivers/infiniband/hw/mlx5/cq.c
index fb6172a9be57..b69ab49b1b3e 100644
--- a/drivers/infiniband/hw/mlx5/cq.c
+++ b/drivers/infiniband/hw/mlx5/cq.c
@@ -760,7 +760,9 @@ static int create_cq_user(struct mlx5_ib_dev *dev, struct ib_udata *udata,
goto err_umem;
}
- err = mlx5_ib_db_map_user(context, ucmd.db_addr, &cq->db);
+ err = mlx5_ib_db_map_user(context, udata,
+ MLX5_IB_ATTR_CREATE_CQ_DBR_BUF_UMEM,
+ ucmd.db_addr, &cq->db);
if (err)
goto err_umem;
@@ -1519,7 +1521,9 @@ ADD_UVERBS_ATTRIBUTES_SIMPLE(
UVERBS_ATTR_PTR_IN(
MLX5_IB_ATTR_CREATE_CQ_UAR_INDEX,
UVERBS_ATTR_TYPE(u32),
- UA_OPTIONAL));
+ UA_OPTIONAL),
+ UVERBS_ATTR_UMEM(MLX5_IB_ATTR_CREATE_CQ_DBR_BUF_UMEM,
+ UA_OPTIONAL));
const struct uapi_definition mlx5_ib_create_cq_defs[] = {
UAPI_DEF_CHAIN_OBJ_TREE(UVERBS_OBJECT_CQ, &mlx5_ib_cq_create),
diff --git a/drivers/infiniband/hw/mlx5/doorbell.c b/drivers/infiniband/hw/mlx5/doorbell.c
index 020c70328663..c9f9b9179e88 100644
--- a/drivers/infiniband/hw/mlx5/doorbell.c
+++ b/drivers/infiniband/hw/mlx5/doorbell.c
@@ -45,20 +45,56 @@ struct mlx5_ib_user_db_page {
struct mm_struct *mm;
};
-int mlx5_ib_db_map_user(struct mlx5_ib_ucontext *context, unsigned long virt,
- struct mlx5_db *db)
+int mlx5_ib_db_map_user(struct mlx5_ib_ucontext *context,
+ struct ib_udata *udata, u16 attr_id,
+ unsigned long virt, struct mlx5_db *db)
{
- struct mlx5_ib_user_db_page *page;
+ struct mlx5_ib_user_db_page *page = NULL;
+ unsigned long dma_offset;
int err = 0;
+ if (udata) {
+ struct ib_umem *umem;
+
+ umem = ib_umem_get_attr(context->ibucontext.device, udata,
+ attr_id, sizeof(__be32) * 2, 0);
+ if (IS_ERR(umem))
+ return PTR_ERR(umem);
+ if (umem) {
+ /*
+ * The 8-byte DBR is programmed to the device as one
+ * DMA address, so it must stay within a single page.
+ * An 8-byte range that crosses a page boundary may
+ * be split across two non-contiguous DMA mappings.
+ */
+ if (ib_umem_offset(umem) >
+ PAGE_SIZE - sizeof(__be32) * 2) {
+ ib_umem_release(umem);
+ return -EINVAL;
+ }
+ page = kzalloc_obj(*page);
+ if (!page) {
+ ib_umem_release(umem);
+ return -ENOMEM;
+ }
+ page->umem = umem;
+ dma_offset = ib_umem_offset(umem);
+ }
+ }
+
mutex_lock(&context->db_page_mutex);
+ if (page)
+ goto add_page;
+
+ dma_offset = virt & ~PAGE_MASK;
+
list_for_each_entry(page, &context->db_page_list, list)
if ((current->mm == page->mm) &&
(page->user_virt == (virt & PAGE_MASK)))
goto found;
- page = kmalloc_obj(*page);
+ page = kzalloc_obj(*page);
if (!page) {
err = -ENOMEM;
goto out;
@@ -76,11 +112,11 @@ int mlx5_ib_db_map_user(struct mlx5_ib_ucontext *context, unsigned long virt,
mmgrab(current->mm);
page->mm = current->mm;
+add_page:
list_add(&page->list, &context->db_page_list);
found:
- db->dma = sg_dma_address(page->umem->sgt_append.sgt.sgl) +
- (virt & ~PAGE_MASK);
+ db->dma = sg_dma_address(page->umem->sgt_append.sgt.sgl) + dma_offset;
db->u.user_page = page;
++page->refcnt;
@@ -96,7 +132,8 @@ void mlx5_ib_db_unmap_user(struct mlx5_ib_ucontext *context, struct mlx5_db *db)
if (!--db->u.user_page->refcnt) {
list_del(&db->u.user_page->list);
- mmdrop(db->u.user_page->mm);
+ if (db->u.user_page->mm)
+ mmdrop(db->u.user_page->mm);
ib_umem_release(db->u.user_page->umem);
kfree(db->u.user_page);
}
diff --git a/drivers/infiniband/hw/mlx5/mlx5_ib.h b/drivers/infiniband/hw/mlx5/mlx5_ib.h
index e156dc4d7529..45bc8928523a 100644
--- a/drivers/infiniband/hw/mlx5/mlx5_ib.h
+++ b/drivers/infiniband/hw/mlx5/mlx5_ib.h
@@ -1259,8 +1259,9 @@ to_mmmap(struct rdma_user_mmap_entry *rdma_entry)
int mlx5_ib_dev_res_cq_init(struct mlx5_ib_dev *dev);
int mlx5_ib_dev_res_srq_init(struct mlx5_ib_dev *dev);
-int mlx5_ib_db_map_user(struct mlx5_ib_ucontext *context, unsigned long virt,
- struct mlx5_db *db);
+int mlx5_ib_db_map_user(struct mlx5_ib_ucontext *context,
+ struct ib_udata *udata, u16 attr_id,
+ unsigned long virt, struct mlx5_db *db);
void mlx5_ib_db_unmap_user(struct mlx5_ib_ucontext *context, struct mlx5_db *db);
void __mlx5_ib_cq_clean(struct mlx5_ib_cq *cq, u32 qpn, struct mlx5_ib_srq *srq);
void mlx5_ib_cq_clean(struct mlx5_ib_cq *cq, u32 qpn, struct mlx5_ib_srq *srq);
diff --git a/drivers/infiniband/hw/mlx5/qp.c b/drivers/infiniband/hw/mlx5/qp.c
index 1b764a573dd7..997ea9bcfc55 100644
--- a/drivers/infiniband/hw/mlx5/qp.c
+++ b/drivers/infiniband/hw/mlx5/qp.c
@@ -918,7 +918,7 @@ static int create_user_rq(struct mlx5_ib_dev *dev, struct ib_pd *pd,
ib_umem_num_pages(rwq->umem), page_size, rwq->rq_num_pas,
offset);
- err = mlx5_ib_db_map_user(ucontext, ucmd->db_addr, &rwq->db);
+ err = mlx5_ib_db_map_user(ucontext, NULL, 0, ucmd->db_addr, &rwq->db);
if (err) {
mlx5_ib_dbg(dev, "map failed\n");
goto err_umem;
@@ -1056,7 +1056,7 @@ static int _create_user_qp(struct mlx5_ib_dev *dev, struct ib_pd *pd,
resp->bfreg_index = MLX5_IB_INVALID_BFREG;
qp->bfregn = bfregn;
- err = mlx5_ib_db_map_user(context, ucmd->db_addr, &qp->db);
+ err = mlx5_ib_db_map_user(context, NULL, 0, ucmd->db_addr, &qp->db);
if (err) {
mlx5_ib_dbg(dev, "map failed\n");
goto err_free;
diff --git a/drivers/infiniband/hw/mlx5/srq.c b/drivers/infiniband/hw/mlx5/srq.c
index bc22036d7e80..88db0143bc3f 100644
--- a/drivers/infiniband/hw/mlx5/srq.c
+++ b/drivers/infiniband/hw/mlx5/srq.c
@@ -74,7 +74,7 @@ static int create_srq_user(struct ib_pd *pd, struct mlx5_ib_srq *srq,
}
in->umem = srq->umem;
- err = mlx5_ib_db_map_user(ucontext, ucmd.db_addr, &srq->db);
+ err = mlx5_ib_db_map_user(ucontext, NULL, 0, ucmd.db_addr, &srq->db);
if (err) {
mlx5_ib_dbg(dev, "map doorbell failed\n");
goto err_umem;
diff --git a/include/uapi/rdma/mlx5_user_ioctl_cmds.h b/include/uapi/rdma/mlx5_user_ioctl_cmds.h
index 01a2a050e468..b63e75034cda 100644
--- a/include/uapi/rdma/mlx5_user_ioctl_cmds.h
+++ b/include/uapi/rdma/mlx5_user_ioctl_cmds.h
@@ -274,6 +274,7 @@ enum mlx5_ib_device_query_context_attrs {
enum mlx5_ib_create_cq_attrs {
MLX5_IB_ATTR_CREATE_CQ_UAR_INDEX = UVERBS_ID_DRIVER_NS_WITH_UHW,
+ MLX5_IB_ATTR_CREATE_CQ_DBR_BUF_UMEM,
};
enum mlx5_ib_reg_dmabuf_mr_attrs {
--
2.53.0
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH rdma-next v3 16/17] RDMA/mlx5: Use UMEM attribute for QP doorbell record
2026-05-04 13:57 [PATCH rdma-next v3 00/17] RDMA: Introduce generic buffer descriptor infrastructure for umem Jiri Pirko
` (14 preceding siblings ...)
2026-05-04 13:57 ` [PATCH rdma-next v3 15/17] RDMA/mlx5: Use UMEM attribute for CQ doorbell record Jiri Pirko
@ 2026-05-04 13:57 ` Jiri Pirko
2026-05-04 13:57 ` [PATCH rdma-next v3 17/17] RDMA/uverbs: Track attr consumption and warn on unused attrs Jiri Pirko
16 siblings, 0 replies; 28+ messages in thread
From: Jiri Pirko @ 2026-05-04 13:57 UTC (permalink / raw)
To: linux-rdma
Cc: jgg, leon, mrgolin, gal.pressman, sleybo, parav, mbloch,
yanjun.zhu, marco.crivellari, roman.gushchin, phaddad, lirongqing,
ynachum, huangjunxian6, kalesh-anakkur.purayil, ohartoov,
michaelgur, shayd, edwards, sriharsha.basavapatna,
andrew.gospodarek, selvin.xavier
From: Jiri Pirko <jiri@nvidia.com>
Add an optional mlx5 driver-namespace UMEM attribute on QP
create so userspace can supply the doorbell record umem
explicitly, symmetric to the CQ side. Resolve it inside
mlx5_ib_db_map_user() and use it as a private DBR page when
present; otherwise take the existing UHW share-or-pin path
that preserves per-page DBR sharing across CQ/QP/SRQ in the
same process.
Add mlx5's first UVERBS_OBJECT_QP UAPI definition chain to
attach the new attr.
Signed-off-by: Jiri Pirko <jiri@nvidia.com>
---
v2->v3:
- moved QP DBR attr to mlx5 driver namespace
- added new mlx5_ib_create_qp_defs[] UAPI chain (mlx5 had only a CQ one)
- changed to use ib_umem_get_attr() to get umem inside
mlx5_ib_db_map_user()
---
drivers/infiniband/hw/mlx5/main.c | 1 +
drivers/infiniband/hw/mlx5/mlx5_ib.h | 1 +
drivers/infiniband/hw/mlx5/qp.c | 19 ++++++++++++++++++-
include/uapi/rdma/mlx5_user_ioctl_cmds.h | 4 ++++
4 files changed, 24 insertions(+), 1 deletion(-)
diff --git a/drivers/infiniband/hw/mlx5/main.c b/drivers/infiniband/hw/mlx5/main.c
index 109661c2ac12..a94cf6dd4992 100644
--- a/drivers/infiniband/hw/mlx5/main.c
+++ b/drivers/infiniband/hw/mlx5/main.c
@@ -4449,6 +4449,7 @@ static const struct uapi_definition mlx5_ib_defs[] = {
UAPI_DEF_CHAIN(mlx5_ib_std_types_defs),
UAPI_DEF_CHAIN(mlx5_ib_dm_defs),
UAPI_DEF_CHAIN(mlx5_ib_create_cq_defs),
+ UAPI_DEF_CHAIN(mlx5_ib_create_qp_defs),
UAPI_DEF_CHAIN_OBJ_TREE(UVERBS_OBJECT_DEVICE, &mlx5_ib_query_context),
UAPI_DEF_CHAIN_OBJ_TREE(UVERBS_OBJECT_MR, &mlx5_ib_reg_dmabuf_mr),
diff --git a/drivers/infiniband/hw/mlx5/mlx5_ib.h b/drivers/infiniband/hw/mlx5/mlx5_ib.h
index 45bc8928523a..5ea0b755a000 100644
--- a/drivers/infiniband/hw/mlx5/mlx5_ib.h
+++ b/drivers/infiniband/hw/mlx5/mlx5_ib.h
@@ -1511,6 +1511,7 @@ extern const struct uapi_definition mlx5_ib_flow_defs[];
extern const struct uapi_definition mlx5_ib_qos_defs[];
extern const struct uapi_definition mlx5_ib_std_types_defs[];
extern const struct uapi_definition mlx5_ib_create_cq_defs[];
+extern const struct uapi_definition mlx5_ib_create_qp_defs[];
static inline int is_qp1(enum ib_qp_type qp_type)
{
diff --git a/drivers/infiniband/hw/mlx5/qp.c b/drivers/infiniband/hw/mlx5/qp.c
index 997ea9bcfc55..d384dd17b19c 100644
--- a/drivers/infiniband/hw/mlx5/qp.c
+++ b/drivers/infiniband/hw/mlx5/qp.c
@@ -44,6 +44,9 @@
#include "qp.h"
#include "wr.h"
+#define UVERBS_MODULE_NAME mlx5_ib
+#include <rdma/uverbs_named_ioctl.h>
+
enum {
MLX5_IB_ACK_REQ_FREQ = 8,
};
@@ -1056,7 +1059,9 @@ static int _create_user_qp(struct mlx5_ib_dev *dev, struct ib_pd *pd,
resp->bfreg_index = MLX5_IB_INVALID_BFREG;
qp->bfregn = bfregn;
- err = mlx5_ib_db_map_user(context, NULL, 0, ucmd->db_addr, &qp->db);
+ err = mlx5_ib_db_map_user(context, udata,
+ MLX5_IB_ATTR_CREATE_QP_DBR_BUF_UMEM,
+ ucmd->db_addr, &qp->db);
if (err) {
mlx5_ib_dbg(dev, "map failed\n");
goto err_free;
@@ -5871,3 +5876,15 @@ void mlx5_ib_qp_event_cleanup(void)
{
destroy_workqueue(mlx5_ib_qp_event_wq);
}
+
+ADD_UVERBS_ATTRIBUTES_SIMPLE(
+ mlx5_ib_qp_create,
+ UVERBS_OBJECT_QP,
+ UVERBS_METHOD_QP_CREATE,
+ UVERBS_ATTR_UMEM(MLX5_IB_ATTR_CREATE_QP_DBR_BUF_UMEM,
+ UA_OPTIONAL));
+
+const struct uapi_definition mlx5_ib_create_qp_defs[] = {
+ UAPI_DEF_CHAIN_OBJ_TREE(UVERBS_OBJECT_QP, &mlx5_ib_qp_create),
+ {},
+};
diff --git a/include/uapi/rdma/mlx5_user_ioctl_cmds.h b/include/uapi/rdma/mlx5_user_ioctl_cmds.h
index b63e75034cda..ddb898afd813 100644
--- a/include/uapi/rdma/mlx5_user_ioctl_cmds.h
+++ b/include/uapi/rdma/mlx5_user_ioctl_cmds.h
@@ -277,6 +277,10 @@ enum mlx5_ib_create_cq_attrs {
MLX5_IB_ATTR_CREATE_CQ_DBR_BUF_UMEM,
};
+enum mlx5_ib_create_qp_attrs {
+ MLX5_IB_ATTR_CREATE_QP_DBR_BUF_UMEM = UVERBS_ID_DRIVER_NS_WITH_UHW,
+};
+
enum mlx5_ib_reg_dmabuf_mr_attrs {
MLX5_IB_ATTR_REG_DMABUF_MR_ACCESS_FLAGS = (1U << UVERBS_ID_NS_SHIFT),
};
--
2.53.0
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH rdma-next v3 17/17] RDMA/uverbs: Track attr consumption and warn on unused attrs
2026-05-04 13:57 [PATCH rdma-next v3 00/17] RDMA: Introduce generic buffer descriptor infrastructure for umem Jiri Pirko
` (15 preceding siblings ...)
2026-05-04 13:57 ` [PATCH rdma-next v3 16/17] RDMA/mlx5: Use UMEM attribute for QP " Jiri Pirko
@ 2026-05-04 13:57 ` Jiri Pirko
2026-05-06 13:56 ` Jason Gunthorpe
16 siblings, 1 reply; 28+ messages in thread
From: Jiri Pirko @ 2026-05-04 13:57 UTC (permalink / raw)
To: linux-rdma
Cc: jgg, leon, mrgolin, gal.pressman, sleybo, parav, mbloch,
yanjun.zhu, marco.crivellari, roman.gushchin, phaddad, lirongqing,
ynachum, huangjunxian6, kalesh-anakkur.purayil, ohartoov,
michaelgur, shayd, edwards, sriharsha.basavapatna,
andrew.gospodarek, selvin.xavier
From: Jiri Pirko <jiri@nvidia.com>
Catch userspace passing attributes that nothing in the kernel
reads which would be a sign that the driver doesn't support
a feature, an attr was forgotten in a refactor, or userspace is buggy.
UHW and PTR_OUT attrs are exempt; destroy attrs are marked consumed by
the framework. Gate on CONFIG_DEBUG_KERNEL to avoid overhead on
production kernels.
Signed-off-by: Jiri Pirko <jiri@nvidia.com>
---
v2->v3:
- new patch
---
drivers/infiniband/core/rdma_core.h | 2 +-
drivers/infiniband/core/uverbs_ioctl.c | 55 +++++++++++++++++++++++---
include/rdma/uverbs_ioctl.h | 54 ++++++++++++++-----------
3 files changed, 82 insertions(+), 29 deletions(-)
diff --git a/drivers/infiniband/core/rdma_core.h b/drivers/infiniband/core/rdma_core.h
index 269b393799ab..06b735f6b3ac 100644
--- a/drivers/infiniband/core/rdma_core.h
+++ b/drivers/infiniband/core/rdma_core.h
@@ -67,7 +67,7 @@ void uverbs_finalize_object(struct ib_uobject *uobj,
enum uverbs_obj_access access, bool hw_obj_valid,
bool commit, struct uverbs_attr_bundle *attrs);
-int uverbs_output_written(const struct uverbs_attr_bundle *bundle, size_t idx);
+int uverbs_output_written(struct uverbs_attr_bundle *bundle, size_t idx);
void setup_ufile_idr_uobject(struct ib_uverbs_file *ufile);
void release_ufile_idr_uobject(struct ib_uverbs_file *ufile);
diff --git a/drivers/infiniband/core/uverbs_ioctl.c b/drivers/infiniband/core/uverbs_ioctl.c
index a2182d3401da..e626b7f4e6eb 100644
--- a/drivers/infiniband/core/uverbs_ioctl.c
+++ b/drivers/infiniband/core/uverbs_ioctl.c
@@ -438,6 +438,40 @@ static int uverbs_set_attr(struct bundle_priv *pbundle,
return 0;
}
+#if IS_ENABLED(CONFIG_DEBUG_KERNEL)
+static void uverbs_check_attr_consumption(struct bundle_priv *pbundle)
+{
+ const struct uverbs_api_ioctl_method *method = pbundle->method_elm;
+ struct uverbs_attr_bundle *bundle =
+ container_of(&pbundle->bundle, struct uverbs_attr_bundle, hdr);
+ unsigned int bkey;
+
+ for_each_set_bit(bkey, bundle->attr_present, method->key_bitmap_len) {
+ const struct uverbs_api_attr *attr_uapi;
+ const struct uverbs_attr_spec *spec;
+ void __rcu **slot;
+
+ if (test_bit(bkey, bundle->attr_consumed))
+ continue;
+
+ slot = uapi_get_attr_for_method(pbundle,
+ uapi_bkey_to_key_attr(bkey));
+ if (!slot)
+ continue;
+ attr_uapi = rcu_dereference_protected(*slot, true);
+ spec = &attr_uapi->spec;
+
+ if (spec->is_udata)
+ continue;
+ if (spec->type == UVERBS_ATTR_TYPE_PTR_OUT)
+ continue;
+
+ pr_warn_ratelimited("uverbs: method_key=0x%x bkey=%u attr provided by user but not consumed\n",
+ pbundle->method_key, bkey);
+ }
+}
+#endif
+
static int ib_uverbs_run_method(struct bundle_priv *pbundle,
unsigned int num_attrs)
{
@@ -487,6 +521,9 @@ static int ib_uverbs_run_method(struct bundle_priv *pbundle,
if (ret)
return ret;
__clear_bit(destroy_bkey, pbundle->uobj_finalize);
+#if IS_ENABLED(CONFIG_DEBUG_KERNEL)
+ __set_bit(destroy_bkey, bundle->attr_consumed);
+#endif
ret = handler(bundle);
uobj_put_destroy(destroy_attr->uobject);
@@ -515,6 +552,10 @@ static int ib_uverbs_run_method(struct bundle_priv *pbundle,
if (WARN_ON_ONCE(ret == -EPROTONOSUPPORT))
return -EINVAL;
+#if IS_ENABLED(CONFIG_DEBUG_KERNEL)
+ if (!ret)
+ uverbs_check_attr_consumption(pbundle);
+#endif
return ret;
}
@@ -623,6 +664,10 @@ static int ib_uverbs_cmd_verbs(struct ib_uverbs_file *ufile,
sizeof(*pbundle->internal_buffer));
memset(pbundle->bundle.attr_present, 0,
sizeof(pbundle->bundle.attr_present));
+#if IS_ENABLED(CONFIG_DEBUG_KERNEL)
+ memset(pbundle->bundle.attr_consumed, 0,
+ sizeof(pbundle->bundle.attr_consumed));
+#endif
memset(pbundle->uobj_finalize, 0, sizeof(pbundle->uobj_finalize));
memset(pbundle->spec_finalize, 0, sizeof(pbundle->spec_finalize));
memset(pbundle->uobj_hw_obj_valid, 0,
@@ -662,7 +707,7 @@ long ib_uverbs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
return err;
}
-int uverbs_get_flags64(u64 *to, const struct uverbs_attr_bundle *attrs_bundle,
+int uverbs_get_flags64(u64 *to, struct uverbs_attr_bundle *attrs_bundle,
size_t idx, u64 allowed_bits)
{
const struct uverbs_attr *attr;
@@ -695,7 +740,7 @@ int uverbs_get_flags64(u64 *to, const struct uverbs_attr_bundle *attrs_bundle,
}
EXPORT_SYMBOL(uverbs_get_flags64);
-int uverbs_get_flags32(u32 *to, const struct uverbs_attr_bundle *attrs_bundle,
+int uverbs_get_flags32(u32 *to, struct uverbs_attr_bundle *attrs_bundle,
size_t idx, u64 allowed_bits)
{
u64 flags;
@@ -753,7 +798,7 @@ void uverbs_fill_udata(struct uverbs_attr_bundle *bundle,
}
}
-int uverbs_copy_to(const struct uverbs_attr_bundle *bundle, size_t idx,
+int uverbs_copy_to(struct uverbs_attr_bundle *bundle, size_t idx,
const void *from, size_t size)
{
const struct uverbs_attr *attr = uverbs_attr_get(bundle, idx);
@@ -775,7 +820,7 @@ EXPORT_SYMBOL(uverbs_copy_to);
* This is only used if the caller has directly used copy_to_use to write the
* data. It signals to user space that the buffer is filled in.
*/
-int uverbs_output_written(const struct uverbs_attr_bundle *bundle, size_t idx)
+int uverbs_output_written(struct uverbs_attr_bundle *bundle, size_t idx)
{
const struct uverbs_attr *attr = uverbs_attr_get(bundle, idx);
@@ -785,7 +830,7 @@ int uverbs_output_written(const struct uverbs_attr_bundle *bundle, size_t idx)
return uverbs_set_output(bundle, attr);
}
-int uverbs_copy_to_struct_or_zero(const struct uverbs_attr_bundle *bundle,
+int uverbs_copy_to_struct_or_zero(struct uverbs_attr_bundle *bundle,
size_t idx, const void *from, size_t size)
{
const struct uverbs_attr *attr = uverbs_attr_get(bundle, idx);
diff --git a/include/rdma/uverbs_ioctl.h b/include/rdma/uverbs_ioctl.h
index 70caa7299dbf..386732094978 100644
--- a/include/rdma/uverbs_ioctl.h
+++ b/include/rdma/uverbs_ioctl.h
@@ -648,6 +648,9 @@ struct uverbs_attr_bundle {
struct ib_ucontext *context;
struct ib_uobject *uobject;
DECLARE_BITMAP(attr_present, UVERBS_API_ATTR_BKEY_LEN);
+#if IS_ENABLED(CONFIG_DEBUG_KERNEL)
+ DECLARE_BITMAP(attr_consumed, UVERBS_API_ATTR_BKEY_LEN);
+#endif
);
struct uverbs_attr attrs[];
};
@@ -683,16 +686,20 @@ struct ib_device *rdma_udata_to_dev(struct ib_udata *udata);
#define IS_UVERBS_COPY_ERR(_ret) ((_ret) && (_ret) != -ENOENT)
-static inline const struct uverbs_attr *uverbs_attr_get(const struct uverbs_attr_bundle *attrs_bundle,
+static inline const struct uverbs_attr *uverbs_attr_get(struct uverbs_attr_bundle *attrs_bundle,
u16 idx)
{
if (!uverbs_attr_is_valid(attrs_bundle, idx))
return ERR_PTR(-ENOENT);
+#if IS_ENABLED(CONFIG_DEBUG_KERNEL)
+ __set_bit(uapi_bkey_attr(uapi_key_attr(idx)),
+ attrs_bundle->attr_consumed);
+#endif
return &attrs_bundle->attrs[uapi_bkey_attr(uapi_key_attr(idx))];
}
-static inline int uverbs_attr_get_enum_id(const struct uverbs_attr_bundle *attrs_bundle,
+static inline int uverbs_attr_get_enum_id(struct uverbs_attr_bundle *attrs_bundle,
u16 idx)
{
const struct uverbs_attr *attr = uverbs_attr_get(attrs_bundle, idx);
@@ -703,7 +710,7 @@ static inline int uverbs_attr_get_enum_id(const struct uverbs_attr_bundle *attrs
return attr->ptr_attr.enum_id;
}
-static inline void *uverbs_attr_get_obj(const struct uverbs_attr_bundle *attrs_bundle,
+static inline void *uverbs_attr_get_obj(struct uverbs_attr_bundle *attrs_bundle,
u16 idx)
{
const struct uverbs_attr *attr;
@@ -715,7 +722,7 @@ static inline void *uverbs_attr_get_obj(const struct uverbs_attr_bundle *attrs_b
return attr->obj_attr.uobject->object;
}
-static inline struct ib_uobject *uverbs_attr_get_uobject(const struct uverbs_attr_bundle *attrs_bundle,
+static inline struct ib_uobject *uverbs_attr_get_uobject(struct uverbs_attr_bundle *attrs_bundle,
u16 idx)
{
const struct uverbs_attr *attr = uverbs_attr_get(attrs_bundle, idx);
@@ -727,7 +734,7 @@ static inline struct ib_uobject *uverbs_attr_get_uobject(const struct uverbs_att
}
static inline int
-uverbs_attr_get_len(const struct uverbs_attr_bundle *attrs_bundle, u16 idx)
+uverbs_attr_get_len(struct uverbs_attr_bundle *attrs_bundle, u16 idx)
{
const struct uverbs_attr *attr = uverbs_attr_get(attrs_bundle, idx);
@@ -771,7 +778,7 @@ uverbs_attr_ptr_get_array_size(struct uverbs_attr_bundle *attrs, u16 idx,
* Return: The array length or 0 if no attribute was provided.
*/
static inline int uverbs_attr_get_uobjs_arr(
- const struct uverbs_attr_bundle *attrs_bundle, u16 attr_idx,
+ struct uverbs_attr_bundle *attrs_bundle, u16 attr_idx,
struct ib_uobject ***arr)
{
const struct uverbs_attr *attr =
@@ -793,7 +800,7 @@ static inline bool uverbs_attr_ptr_is_inline(const struct uverbs_attr *attr)
}
static inline void *uverbs_attr_get_alloced_ptr(
- const struct uverbs_attr_bundle *attrs_bundle, u16 idx)
+ struct uverbs_attr_bundle *attrs_bundle, u16 idx)
{
const struct uverbs_attr *attr = uverbs_attr_get(attrs_bundle, idx);
@@ -805,7 +812,7 @@ static inline void *uverbs_attr_get_alloced_ptr(
}
static inline int _uverbs_copy_from(void *to,
- const struct uverbs_attr_bundle *attrs_bundle,
+ struct uverbs_attr_bundle *attrs_bundle,
size_t idx,
size_t size)
{
@@ -832,7 +839,7 @@ static inline int _uverbs_copy_from(void *to,
}
static inline int _uverbs_copy_from_or_zero(void *to,
- const struct uverbs_attr_bundle *attrs_bundle,
+ struct uverbs_attr_bundle *attrs_bundle,
size_t idx,
size_t size)
{
@@ -869,11 +876,11 @@ ib_uverbs_get_ucontext(const struct uverbs_attr_bundle *attrs)
}
#if IS_ENABLED(CONFIG_INFINIBAND_USER_ACCESS)
-int uverbs_get_flags64(u64 *to, const struct uverbs_attr_bundle *attrs_bundle,
+int uverbs_get_flags64(u64 *to, struct uverbs_attr_bundle *attrs_bundle,
size_t idx, u64 allowed_bits);
-int uverbs_get_flags32(u32 *to, const struct uverbs_attr_bundle *attrs_bundle,
+int uverbs_get_flags32(u32 *to, struct uverbs_attr_bundle *attrs_bundle,
size_t idx, u64 allowed_bits);
-int uverbs_copy_to(const struct uverbs_attr_bundle *attrs_bundle, size_t idx,
+int uverbs_copy_to(struct uverbs_attr_bundle *attrs_bundle, size_t idx,
const void *from, size_t size);
__malloc void *_uverbs_alloc(struct uverbs_attr_bundle *bundle, size_t size,
gfp_t flags);
@@ -902,7 +909,7 @@ static inline __malloc void *uverbs_kcalloc(struct uverbs_attr_bundle *bundle,
static inline int
_uverbs_get_const_signed(s64 *to,
- const struct uverbs_attr_bundle *attrs_bundle,
+ struct uverbs_attr_bundle *attrs_bundle,
size_t idx, s64 lower_bound, u64 upper_bound,
s64 *def_val)
{
@@ -925,7 +932,7 @@ _uverbs_get_const_signed(s64 *to,
static inline int
_uverbs_get_const_unsigned(u64 *to,
- const struct uverbs_attr_bundle *attrs_bundle,
+ struct uverbs_attr_bundle *attrs_bundle,
size_t idx, u64 upper_bound, u64 *def_val)
{
const struct uverbs_attr *attr;
@@ -944,7 +951,8 @@ _uverbs_get_const_unsigned(u64 *to,
return 0;
}
-int uverbs_copy_to_struct_or_zero(const struct uverbs_attr_bundle *bundle,
+
+int uverbs_copy_to_struct_or_zero(struct uverbs_attr_bundle *bundle,
size_t idx, const void *from, size_t size);
int _ib_copy_validate_udata_in(struct ib_udata *udata, void *req,
@@ -952,18 +960,18 @@ int _ib_copy_validate_udata_in(struct ib_udata *udata, void *req,
int _ib_respond_udata(struct ib_udata *udata, const void *src, size_t len);
#else
static inline int
-uverbs_get_flags64(u64 *to, const struct uverbs_attr_bundle *attrs_bundle,
+uverbs_get_flags64(u64 *to, struct uverbs_attr_bundle *attrs_bundle,
size_t idx, u64 allowed_bits)
{
return -EINVAL;
}
static inline int
-uverbs_get_flags32(u32 *to, const struct uverbs_attr_bundle *attrs_bundle,
+uverbs_get_flags32(u32 *to, struct uverbs_attr_bundle *attrs_bundle,
size_t idx, u64 allowed_bits)
{
return -EINVAL;
}
-static inline int uverbs_copy_to(const struct uverbs_attr_bundle *attrs_bundle,
+static inline int uverbs_copy_to(struct uverbs_attr_bundle *attrs_bundle,
size_t idx, const void *from, size_t size)
{
return -EINVAL;
@@ -979,21 +987,21 @@ static inline __malloc void *uverbs_zalloc(struct uverbs_attr_bundle *bundle,
return ERR_PTR(-EINVAL);
}
static inline int
-_uverbs_get_const(s64 *to, const struct uverbs_attr_bundle *attrs_bundle,
+_uverbs_get_const(s64 *to, struct uverbs_attr_bundle *attrs_bundle,
size_t idx, s64 lower_bound, u64 upper_bound,
s64 *def_val)
{
return -EINVAL;
}
static inline int
-uverbs_copy_to_struct_or_zero(const struct uverbs_attr_bundle *bundle,
+uverbs_copy_to_struct_or_zero(struct uverbs_attr_bundle *bundle,
size_t idx, const void *from, size_t size)
{
return -EINVAL;
}
static inline int
_uverbs_get_const_signed(s64 *to,
- const struct uverbs_attr_bundle *attrs_bundle,
+ struct uverbs_attr_bundle *attrs_bundle,
size_t idx, s64 lower_bound, u64 upper_bound,
s64 *def_val)
{
@@ -1001,7 +1009,7 @@ _uverbs_get_const_signed(s64 *to,
}
static inline int
_uverbs_get_const_unsigned(u64 *to,
- const struct uverbs_attr_bundle *attrs_bundle,
+ struct uverbs_attr_bundle *attrs_bundle,
size_t idx, u64 upper_bound, u64 *def_val)
{
return -EINVAL;
@@ -1078,7 +1086,7 @@ static inline int _ib_respond_udata(struct ib_udata *udata, const void *src,
_default))
static inline int
-uverbs_get_raw_fd(int *to, const struct uverbs_attr_bundle *attrs_bundle,
+uverbs_get_raw_fd(int *to, struct uverbs_attr_bundle *attrs_bundle,
size_t idx)
{
return uverbs_get_const_signed(to, attrs_bundle, idx);
--
2.53.0
^ permalink raw reply related [flat|nested] 28+ messages in thread
* Re: [PATCH rdma-next v3 03/17] RDMA/core: Introduce generic buffer descriptor infrastructure for umem
2026-05-04 13:57 ` [PATCH rdma-next v3 03/17] RDMA/core: Introduce generic buffer descriptor infrastructure for umem Jiri Pirko
@ 2026-05-06 13:37 ` Jason Gunthorpe
2026-05-06 14:14 ` Jiri Pirko
0 siblings, 1 reply; 28+ messages in thread
From: Jason Gunthorpe @ 2026-05-06 13:37 UTC (permalink / raw)
To: Jiri Pirko
Cc: linux-rdma, leon, mrgolin, gal.pressman, sleybo, parav, mbloch,
yanjun.zhu, marco.crivellari, roman.gushchin, phaddad, lirongqing,
ynachum, huangjunxian6, kalesh-anakkur.purayil, ohartoov,
michaelgur, shayd, edwards, sriharsha.basavapatna,
andrew.gospodarek, selvin.xavier
On Mon, May 04, 2026 at 03:57:17PM +0200, Jiri Pirko wrote:
> +/**
> + * ib_umem_get - Canonical on-demand umem getter.
> + * @device: IB device.
> + * @udata: uverbs udata bundle (may be NULL).
> + * @attr_id: per-command UMEM attribute id; consulted if @udata is set.
> + * @legacy_filler: optional command-specific legacy attr filler.
> + * invoked if @udata is set.
> + * @va_fallback: if true, build a VA-typed desc with @addr.
> + * @addr: user VA, used if @va_fallback is true.
> + * @size: driver-required minimum length.
> + * @access: IB access flags forwarded to ib_umem_get_desc().
> + *
> + * Return: valid umem on success, ERR_PTR(...) on error, NULL
> + * if no source produced a buffer (only possible when @va_fallback is false).
> + */
> +struct ib_umem *ib_umem_get(struct ib_device *device, struct ib_udata *udata,
> + u16 attr_id,
> + ib_umem_buf_desc_filler_t legacy_filler,
> + bool va_fallback, u64 addr, size_t size, int access)
I didn't try to look at what the drivers actually do, but I'm slightly
surprised not to see an addr_size here? Is it the case the drivers
don't have have a uhw->size to go along with their uhw->va?
I guess mrs always use mr->len and the cq/qps are doing something like
uhw->ncqes*SIZE_CQE?
Did you find any counter example?
> + ret = legacy_filler(attrs, &legacy_desc);
> + if (!ret) {
> + if (have_desc) {
> + ibdev_err(device,
> + "UMEM attr (id=%u) and legacy attrs are mutually exclusive\n",
> + attr_id);
> + return ERR_PTR(-EINVAL);
We must never print on system calls, it just gives a way for unpriv
userspace to fill the dmesg.
> --- a/include/uapi/rdma/ib_user_ioctl_verbs.h
> +++ b/include/uapi/rdma/ib_user_ioctl_verbs.h
> @@ -273,4 +273,27 @@ struct ib_uverbs_gid_entry {
> __u32 netdev_ifindex; /* It is 0 if there is no netdev associated with it */
> };
>
> +enum ib_uverbs_buffer_type {
> + IB_UVERBS_BUFFER_TYPE_DMABUF,
> + IB_UVERBS_BUFFER_TYPE_VA,
> +};
I've learned it helps backporters to add the =0, =1
Jason
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH rdma-next v3 13/17] RDMA/uverbs: Use UMEM attributes for QP creation
2026-05-04 13:57 ` [PATCH rdma-next v3 13/17] RDMA/uverbs: Use UMEM attributes for QP creation Jiri Pirko
@ 2026-05-06 13:43 ` Jason Gunthorpe
2026-05-06 14:17 ` Jiri Pirko
0 siblings, 1 reply; 28+ messages in thread
From: Jason Gunthorpe @ 2026-05-06 13:43 UTC (permalink / raw)
To: Jiri Pirko
Cc: linux-rdma, leon, mrgolin, gal.pressman, sleybo, parav, mbloch,
yanjun.zhu, marco.crivellari, roman.gushchin, phaddad, lirongqing,
ynachum, huangjunxian6, kalesh-anakkur.purayil, ohartoov,
michaelgur, shayd, edwards, sriharsha.basavapatna,
andrew.gospodarek, selvin.xavier
On Mon, May 04, 2026 at 03:57:27PM +0200, Jiri Pirko wrote:
> @@ -340,6 +340,12 @@ DECLARE_UVERBS_NAMED_METHOD(
> UVERBS_ATTR_PTR_OUT(UVERBS_ATTR_CREATE_QP_RESP_QP_NUM,
> UVERBS_ATTR_TYPE(u32),
> UA_MANDATORY),
> + UVERBS_ATTR_UMEM(UVERBS_ATTR_CREATE_QP_BUF_UMEM,
> + UA_OPTIONAL),
> + UVERBS_ATTR_UMEM(UVERBS_ATTR_CREATE_QP_RQ_BUF_UMEM,
> + UA_OPTIONAL),
> + UVERBS_ATTR_UMEM(UVERBS_ATTR_CREATE_QP_SQ_BUF_UMEM,
> + UA_OPTIONAL),
> UVERBS_ATTR_UHW());
could an ai make a summary of how each driver would map its existing
umems to these - add it to the commit message?
Trying to guess if it is general? RQ/SQ seem reasonable, but I'm
wondering what drivers will use QP_BUF for...
Jason
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH rdma-next v3 07/17] RDMA/uverbs: Add CQ buffer UMEM attribute and driver helpers
2026-05-04 13:57 ` [PATCH rdma-next v3 07/17] RDMA/uverbs: Add CQ buffer UMEM attribute and driver helpers Jiri Pirko
@ 2026-05-06 13:46 ` Jason Gunthorpe
2026-05-06 14:27 ` Jiri Pirko
0 siblings, 1 reply; 28+ messages in thread
From: Jason Gunthorpe @ 2026-05-06 13:46 UTC (permalink / raw)
To: Jiri Pirko
Cc: linux-rdma, leon, mrgolin, gal.pressman, sleybo, parav, mbloch,
yanjun.zhu, marco.crivellari, roman.gushchin, phaddad, lirongqing,
ynachum, huangjunxian6, kalesh-anakkur.purayil, ohartoov,
michaelgur, shayd, edwards, sriharsha.basavapatna,
andrew.gospodarek, selvin.xavier
On Mon, May 04, 2026 at 03:57:21PM +0200, Jiri Pirko wrote:
> From: Jiri Pirko <jiri@nvidia.com>
>
> Add UVERBS_ATTR_CREATE_CQ_BUF_UMEM and two driver-facing
> wrappers, ib_umem_get_cq_buf() and ib_umem_get_cq_buf_or_va(),
> that pin a CQ buffer umem from it. The wrappers reuse the
> existing legacy CQ buffer-attr filler.
Did you look at converting all drivers to use
ib_umem_get_cq_buf_or_va()? Is it just a quick cocinille job?
The QP one is probably an AI job..
Jason
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH rdma-next v3 08/17] RDMA/efa: Use ib_umem_get_cq_buf() for user CQ buffer
2026-05-04 13:57 ` [PATCH rdma-next v3 08/17] RDMA/efa: Use ib_umem_get_cq_buf() for user CQ buffer Jiri Pirko
@ 2026-05-06 13:51 ` Jason Gunthorpe
2026-05-06 14:32 ` Jiri Pirko
0 siblings, 1 reply; 28+ messages in thread
From: Jason Gunthorpe @ 2026-05-06 13:51 UTC (permalink / raw)
To: Jiri Pirko
Cc: linux-rdma, leon, mrgolin, gal.pressman, sleybo, parav, mbloch,
yanjun.zhu, marco.crivellari, roman.gushchin, phaddad, lirongqing,
ynachum, huangjunxian6, kalesh-anakkur.purayil, ohartoov,
michaelgur, shayd, edwards, sriharsha.basavapatna,
andrew.gospodarek, selvin.xavier
On Mon, May 04, 2026 at 03:57:22PM +0200, Jiri Pirko wrote:
> @@ -1172,26 +1174,29 @@ int efa_create_user_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr,
> cq->ucontext = ucontext;
> cq->size = PAGE_ALIGN(cmd.cq_entry_size * entries * cmd.num_sub_cqs);
>
> - if (ibcq->umem) {
> - if (ibcq->umem->length < cq->size) {
> - ibdev_dbg(&dev->ibdev, "External memory too small\n");
> - err = -EINVAL;
> - goto err_out;
> - }
> + umem = ib_umem_get_cq_buf(ibcq->device, udata, cq->size,
> + IB_ACCESS_LOCAL_WRITE);
> + if (IS_ERR(umem)) {
> + err = PTR_ERR(umem);
> + goto err_out;
> + }
> +
> + cq->umem = umem;
>
> - if (!ib_umem_is_contiguous(ibcq->umem)) {
> + if (umem) {
> + if (!ib_umem_is_contiguous(umem)) {
This is a little funny, I think umem should not be NULL?
I'd rather the ib_umem_get() not be called if the op is in kernel mode
(this is user_cq so it is never in kernel mode so it should never be
null)
Meaning return a valid umem or return ERR_PTR, never null?
The case that is now NULL should be EINVAL (bad system call arguments)
Jason
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH rdma-next v3 17/17] RDMA/uverbs: Track attr consumption and warn on unused attrs
2026-05-04 13:57 ` [PATCH rdma-next v3 17/17] RDMA/uverbs: Track attr consumption and warn on unused attrs Jiri Pirko
@ 2026-05-06 13:56 ` Jason Gunthorpe
2026-05-06 14:22 ` Jiri Pirko
0 siblings, 1 reply; 28+ messages in thread
From: Jason Gunthorpe @ 2026-05-06 13:56 UTC (permalink / raw)
To: Jiri Pirko
Cc: linux-rdma, leon, mrgolin, gal.pressman, sleybo, parav, mbloch,
yanjun.zhu, marco.crivellari, roman.gushchin, phaddad, lirongqing,
ynachum, huangjunxian6, kalesh-anakkur.purayil, ohartoov,
michaelgur, shayd, edwards, sriharsha.basavapatna,
andrew.gospodarek, selvin.xavier
On Mon, May 04, 2026 at 03:57:31PM +0200, Jiri Pirko wrote:
> From: Jiri Pirko <jiri@nvidia.com>
>
> Catch userspace passing attributes that nothing in the kernel
> reads which would be a sign that the driver doesn't support
> a feature, an attr was forgotten in a refactor, or userspace is buggy.
> UHW and PTR_OUT attrs are exempt; destroy attrs are marked consumed by
> the framework. Gate on CONFIG_DEBUG_KERNEL to avoid overhead on
> production kernels.
This is maybe interesting debugging for a version matched rdma-core
But the idea the kernel ignores an attribute is part of the protocol,
if the attribute is marked mandatory by userspace then the kernel will
fail the system call.
I don't remember how often this ends up being used, and I think it is
a bit rare, but it is there.
Jason
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH rdma-next v3 03/17] RDMA/core: Introduce generic buffer descriptor infrastructure for umem
2026-05-06 13:37 ` Jason Gunthorpe
@ 2026-05-06 14:14 ` Jiri Pirko
0 siblings, 0 replies; 28+ messages in thread
From: Jiri Pirko @ 2026-05-06 14:14 UTC (permalink / raw)
To: Jason Gunthorpe
Cc: linux-rdma, leon, mrgolin, gal.pressman, sleybo, parav, mbloch,
yanjun.zhu, marco.crivellari, roman.gushchin, phaddad, lirongqing,
ynachum, huangjunxian6, kalesh-anakkur.purayil, ohartoov,
michaelgur, shayd, edwards, sriharsha.basavapatna,
andrew.gospodarek, selvin.xavier
Wed, May 06, 2026 at 03:37:57PM +0200, jgg@ziepe.ca wrote:
>On Mon, May 04, 2026 at 03:57:17PM +0200, Jiri Pirko wrote:
>
>> +/**
>> + * ib_umem_get - Canonical on-demand umem getter.
>> + * @device: IB device.
>> + * @udata: uverbs udata bundle (may be NULL).
>> + * @attr_id: per-command UMEM attribute id; consulted if @udata is set.
>> + * @legacy_filler: optional command-specific legacy attr filler.
>> + * invoked if @udata is set.
>> + * @va_fallback: if true, build a VA-typed desc with @addr.
>> + * @addr: user VA, used if @va_fallback is true.
>> + * @size: driver-required minimum length.
>> + * @access: IB access flags forwarded to ib_umem_get_desc().
>> + *
>> + * Return: valid umem on success, ERR_PTR(...) on error, NULL
>> + * if no source produced a buffer (only possible when @va_fallback is false).
>> + */
>> +struct ib_umem *ib_umem_get(struct ib_device *device, struct ib_udata *udata,
>> + u16 attr_id,
>> + ib_umem_buf_desc_filler_t legacy_filler,
>> + bool va_fallback, u64 addr, size_t size, int access)
>
>I didn't try to look at what the drivers actually do, but I'm slightly
>surprised not to see an addr_size here? Is it the case the drivers
>don't have have a uhw->size to go along with their uhw->va?
"size_t size". What am I missing?
>
>I guess mrs always use mr->len and the cq/qps are doing something like
>uhw->ncqes*SIZE_CQE?
>
>Did you find any counter example?
>
>> + ret = legacy_filler(attrs, &legacy_desc);
>> + if (!ret) {
>> + if (have_desc) {
>> + ibdev_err(device,
>> + "UMEM attr (id=%u) and legacy attrs are mutually exclusive\n",
>> + attr_id);
>> + return ERR_PTR(-EINVAL);
>
>We must never print on system calls, it just gives a way for unpriv
>userspace to fill the dmesg.
Sure. Will fix.
>
>> --- a/include/uapi/rdma/ib_user_ioctl_verbs.h
>> +++ b/include/uapi/rdma/ib_user_ioctl_verbs.h
>> @@ -273,4 +273,27 @@ struct ib_uverbs_gid_entry {
>> __u32 netdev_ifindex; /* It is 0 if there is no netdev associated with it */
>> };
>>
>> +enum ib_uverbs_buffer_type {
>> + IB_UVERBS_BUFFER_TYPE_DMABUF,
>> + IB_UVERBS_BUFFER_TYPE_VA,
>> +};
>
>I've learned it helps backporters to add the =0, =1
Why do we care about backporters? I mean, the mainline code is what we
care of, and for that, enum default values are well defined and enough.
What am I missing?
>
>Jason
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH rdma-next v3 13/17] RDMA/uverbs: Use UMEM attributes for QP creation
2026-05-06 13:43 ` Jason Gunthorpe
@ 2026-05-06 14:17 ` Jiri Pirko
0 siblings, 0 replies; 28+ messages in thread
From: Jiri Pirko @ 2026-05-06 14:17 UTC (permalink / raw)
To: Jason Gunthorpe
Cc: linux-rdma, leon, mrgolin, gal.pressman, sleybo, parav, mbloch,
yanjun.zhu, marco.crivellari, roman.gushchin, phaddad, lirongqing,
ynachum, huangjunxian6, kalesh-anakkur.purayil, ohartoov,
michaelgur, shayd, edwards, sriharsha.basavapatna,
andrew.gospodarek, selvin.xavier
Wed, May 06, 2026 at 03:43:46PM +0200, jgg@ziepe.ca wrote:
>On Mon, May 04, 2026 at 03:57:27PM +0200, Jiri Pirko wrote:
>> @@ -340,6 +340,12 @@ DECLARE_UVERBS_NAMED_METHOD(
>> UVERBS_ATTR_PTR_OUT(UVERBS_ATTR_CREATE_QP_RESP_QP_NUM,
>> UVERBS_ATTR_TYPE(u32),
>> UA_MANDATORY),
>> + UVERBS_ATTR_UMEM(UVERBS_ATTR_CREATE_QP_BUF_UMEM,
>> + UA_OPTIONAL),
>> + UVERBS_ATTR_UMEM(UVERBS_ATTR_CREATE_QP_RQ_BUF_UMEM,
>> + UA_OPTIONAL),
>> + UVERBS_ATTR_UMEM(UVERBS_ATTR_CREATE_QP_SQ_BUF_UMEM,
>> + UA_OPTIONAL),
>> UVERBS_ATTR_UHW());
>
>could an ai make a summary of how each driver would map its existing
>umems to these - add it to the commit message?
>
>Trying to guess if it is general? RQ/SQ seem reasonable, but I'm
>wondering what drivers will use QP_BUF for...
BUF_UMEM is for shared RX/TX QP
[RS]Q_BUF_UMEM are for separete ones, like raw QP in mlx5.
Will document it.
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH rdma-next v3 17/17] RDMA/uverbs: Track attr consumption and warn on unused attrs
2026-05-06 13:56 ` Jason Gunthorpe
@ 2026-05-06 14:22 ` Jiri Pirko
0 siblings, 0 replies; 28+ messages in thread
From: Jiri Pirko @ 2026-05-06 14:22 UTC (permalink / raw)
To: Jason Gunthorpe
Cc: linux-rdma, leon, mrgolin, gal.pressman, sleybo, parav, mbloch,
yanjun.zhu, marco.crivellari, roman.gushchin, phaddad, lirongqing,
ynachum, huangjunxian6, kalesh-anakkur.purayil, ohartoov,
michaelgur, shayd, edwards, sriharsha.basavapatna,
andrew.gospodarek, selvin.xavier
Wed, May 06, 2026 at 03:56:23PM +0200, jgg@ziepe.ca wrote:
>On Mon, May 04, 2026 at 03:57:31PM +0200, Jiri Pirko wrote:
>> From: Jiri Pirko <jiri@nvidia.com>
>>
>> Catch userspace passing attributes that nothing in the kernel
>> reads which would be a sign that the driver doesn't support
>> a feature, an attr was forgotten in a refactor, or userspace is buggy.
>> UHW and PTR_OUT attrs are exempt; destroy attrs are marked consumed by
>> the framework. Gate on CONFIG_DEBUG_KERNEL to avoid overhead on
>> production kernels.
>
>This is maybe interesting debugging for a version matched rdma-core
>
>But the idea the kernel ignores an attribute is part of the protocol,
I'm okay to drop this patch then.
>if the attribute is marked mandatory by userspace then the kernel will
>fail the system call.
>
>I don't remember how often this ends up being used, and I think it is
>a bit rare, but it is there.
>
>Jason
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH rdma-next v3 07/17] RDMA/uverbs: Add CQ buffer UMEM attribute and driver helpers
2026-05-06 13:46 ` Jason Gunthorpe
@ 2026-05-06 14:27 ` Jiri Pirko
0 siblings, 0 replies; 28+ messages in thread
From: Jiri Pirko @ 2026-05-06 14:27 UTC (permalink / raw)
To: Jason Gunthorpe
Cc: linux-rdma, leon, mrgolin, gal.pressman, sleybo, parav, mbloch,
yanjun.zhu, marco.crivellari, roman.gushchin, phaddad, lirongqing,
ynachum, huangjunxian6, kalesh-anakkur.purayil, ohartoov,
michaelgur, shayd, edwards, sriharsha.basavapatna,
andrew.gospodarek, selvin.xavier
Wed, May 06, 2026 at 03:46:38PM +0200, jgg@ziepe.ca wrote:
>On Mon, May 04, 2026 at 03:57:21PM +0200, Jiri Pirko wrote:
>> From: Jiri Pirko <jiri@nvidia.com>
>>
>> Add UVERBS_ATTR_CREATE_CQ_BUF_UMEM and two driver-facing
>> wrappers, ib_umem_get_cq_buf() and ib_umem_get_cq_buf_or_va(),
>> that pin a CQ buffer umem from it. The wrappers reuse the
>> existing legacy CQ buffer-attr filler.
>
>Did you look at converting all drivers to use
>ib_umem_get_cq_buf_or_va()? Is it just a quick cocinille job?
Didn't check if ib_umem_get_cq_buf_or_va(), some driver may use
ib_umem_get_cq_buf() (like EFA does) but yes, that is planned as
a follow-up patch to convert the rest. Should not be hard.
>
>The QP one is probably an AI job..
The QP, I'm not sure about. I can check that out for follow-up, but
I assume this will be non trivial.
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH rdma-next v3 08/17] RDMA/efa: Use ib_umem_get_cq_buf() for user CQ buffer
2026-05-06 13:51 ` Jason Gunthorpe
@ 2026-05-06 14:32 ` Jiri Pirko
0 siblings, 0 replies; 28+ messages in thread
From: Jiri Pirko @ 2026-05-06 14:32 UTC (permalink / raw)
To: Jason Gunthorpe
Cc: linux-rdma, leon, mrgolin, gal.pressman, sleybo, parav, mbloch,
yanjun.zhu, marco.crivellari, roman.gushchin, phaddad, lirongqing,
ynachum, huangjunxian6, kalesh-anakkur.purayil, ohartoov,
michaelgur, shayd, edwards, sriharsha.basavapatna,
andrew.gospodarek, selvin.xavier
Wed, May 06, 2026 at 03:51:39PM +0200, jgg@ziepe.ca wrote:
>On Mon, May 04, 2026 at 03:57:22PM +0200, Jiri Pirko wrote:
>
>> @@ -1172,26 +1174,29 @@ int efa_create_user_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr,
>> cq->ucontext = ucontext;
>> cq->size = PAGE_ALIGN(cmd.cq_entry_size * entries * cmd.num_sub_cqs);
>>
>> - if (ibcq->umem) {
>> - if (ibcq->umem->length < cq->size) {
>> - ibdev_dbg(&dev->ibdev, "External memory too small\n");
>> - err = -EINVAL;
>> - goto err_out;
>> - }
>> + umem = ib_umem_get_cq_buf(ibcq->device, udata, cq->size,
>> + IB_ACCESS_LOCAL_WRITE);
>> + if (IS_ERR(umem)) {
>> + err = PTR_ERR(umem);
>> + goto err_out;
>> + }
>> +
>> + cq->umem = umem;
>>
>> - if (!ib_umem_is_contiguous(ibcq->umem)) {
>> + if (umem) {
>> + if (!ib_umem_is_contiguous(umem)) {
>
>This is a little funny, I think umem should not be NULL?
Yes it is null when there are no CQ umem attrs present. That is
perfectly fine flow.
>
>I'd rather the ib_umem_get() not be called if the op is in kernel mode
>(this is user_cq so it is never in kernel mode so it should never be
>null)
>
>Meaning return a valid umem or return ERR_PTR, never null?
>
>The case that is now NULL should be EINVAL (bad system call arguments)
I was thinking about the ib_umem_get() return value scheme and went back
and forth multiple times, I converged to PTR_ERR in case of something
went wrong and null in case of attrs missing, which I believe is the
best option. It is documented in ib_umem_get kdoc.
^ permalink raw reply [flat|nested] 28+ messages in thread
end of thread, other threads:[~2026-05-06 14:32 UTC | newest]
Thread overview: 28+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-04 13:57 [PATCH rdma-next v3 00/17] RDMA: Introduce generic buffer descriptor infrastructure for umem Jiri Pirko
2026-05-04 13:57 ` [PATCH rdma-next v3 01/17] RDMA/umem: Rename ib_umem_get() to ib_umem_get_va() Jiri Pirko
2026-05-04 13:57 ` [PATCH rdma-next v3 02/17] RDMA/umem: Split ib_umem_get_va() into a thin wrapper around __ib_umem_get_va() Jiri Pirko
2026-05-04 13:57 ` [PATCH rdma-next v3 03/17] RDMA/core: Introduce generic buffer descriptor infrastructure for umem Jiri Pirko
2026-05-06 13:37 ` Jason Gunthorpe
2026-05-06 14:14 ` Jiri Pirko
2026-05-04 13:57 ` [PATCH rdma-next v3 04/17] RDMA/umem: Route ib_umem_get_va() through ib_umem_get() Jiri Pirko
2026-05-04 13:57 ` [PATCH rdma-next v3 05/17] RDMA/uverbs: Inline _uverbs_get_const_{signed,unsigned}() Jiri Pirko
2026-05-04 13:57 ` [PATCH rdma-next v3 06/17] RDMA/uverbs: Push out CQ buffer umem processing into a helper Jiri Pirko
2026-05-04 13:57 ` [PATCH rdma-next v3 07/17] RDMA/uverbs: Add CQ buffer UMEM attribute and driver helpers Jiri Pirko
2026-05-06 13:46 ` Jason Gunthorpe
2026-05-06 14:27 ` Jiri Pirko
2026-05-04 13:57 ` [PATCH rdma-next v3 08/17] RDMA/efa: Use ib_umem_get_cq_buf() for user CQ buffer Jiri Pirko
2026-05-06 13:51 ` Jason Gunthorpe
2026-05-06 14:32 ` Jiri Pirko
2026-05-04 13:57 ` [PATCH rdma-next v3 09/17] RDMA/mlx5: Use ib_umem_get_cq_buf_or_va() " Jiri Pirko
2026-05-04 13:57 ` [PATCH rdma-next v3 10/17] RDMA/bnxt_re: " Jiri Pirko
2026-05-04 13:57 ` [PATCH rdma-next v3 11/17] RDMA/mlx4: Use ib_umem_get_cq_buf() " Jiri Pirko
2026-05-04 13:57 ` [PATCH rdma-next v3 12/17] RDMA/uverbs: Remove legacy umem field from struct ib_cq Jiri Pirko
2026-05-04 13:57 ` [PATCH rdma-next v3 13/17] RDMA/uverbs: Use UMEM attributes for QP creation Jiri Pirko
2026-05-06 13:43 ` Jason Gunthorpe
2026-05-06 14:17 ` Jiri Pirko
2026-05-04 13:57 ` [PATCH rdma-next v3 14/17] RDMA/mlx5: Use UMEM attributes for QP buffers in create_qp Jiri Pirko
2026-05-04 13:57 ` [PATCH rdma-next v3 15/17] RDMA/mlx5: Use UMEM attribute for CQ doorbell record Jiri Pirko
2026-05-04 13:57 ` [PATCH rdma-next v3 16/17] RDMA/mlx5: Use UMEM attribute for QP " Jiri Pirko
2026-05-04 13:57 ` [PATCH rdma-next v3 17/17] RDMA/uverbs: Track attr consumption and warn on unused attrs Jiri Pirko
2026-05-06 13:56 ` Jason Gunthorpe
2026-05-06 14:22 ` Jiri Pirko
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox