From: Yishai Hadas <yishaih@nvidia.com>
To: <jgg@ziepe.ca>, <leon@kernel.org>
Cc: <linux-rdma@vger.kernel.org>, <selvin.xavier@broadcom.com>,
<kalesh-anakkur.purayil@broadcom.com>,
<chengyou@linux.alibaba.com>, <kaishen@linux.alibaba.com>,
<tangchengchang@huawei.com>, <huangjunxian6@hisilicon.com>,
<abhijit.gangurde@amd.com>, <allen.hubbe@amd.com>,
<longli@microsoft.com>, <kotaranov@microsoft.com>,
<mkalderon@marvell.com>, <bryan-bt.tan@broadcom.com>,
<vishnu.dasa@broadcom.com>, <yishaih@nvidia.com>,
<maorg@nvidia.com>
Subject: [PATCH rdma-next 04/15] RDMA/umem: Reuse ib_umem_get_cq_buf_or_va() for VA-only CQ pinning
Date: Tue, 8 Sep 2026 18:28:40 +0300 [thread overview]
Message-ID: <20260908152851.1307294-5-yishaih@nvidia.com> (raw)
In-Reply-To: <20260908152851.1307294-1-yishaih@nvidia.com>
Several drivers pin a CQ ring buffer directly from a plain UHW VA
instead of going through the per-command UMEM attribute machinery,
calling the generic ib_umem_get_va() with IB_ACCESS_LOCAL_WRITE:
- mlx5's resize_user() (CQ resize)
- mlx4's legacy fallback in mlx4_ib_create_user_cq() (no UMEM
attribute source available) and mlx4_alloc_resize_umem() (CQ
resize)
- bnxt_re_resize_cq() (CQ resize)
- ionic's ionic_create_cq_common()
- qedr_create_cq(), via the shared qedr_init_user_queue() helper
- mana_ib_create_cq(), via the shared mana_ib_create_queue() helper
- erdma_init_user_cq(), via the shared get_mtt_entries() helper
- hns_roce_cq.c's alloc_cq_buf(), via the shared
hns_roce_mtr_create() helper
ib_umem_get_cq_buf_or_va() already falls back to a plain VA pin whenever
its attrs argument is NULL (ib_umem_resolve_desc() returns -ENOENT
immediately for attrs == NULL, before ever touching
attr_id/legacy_filler) -- the same attrs=NULL idiom ib_umem_get_va()
itself already uses via ib_umem_get_attr_or_va(device, NULL, 0, addr,
size, access). Switch these call sites to
ib_umem_get_cq_buf_or_va(device, NULL, addr, size, access) instead of
ib_umem_get_va(), so all CQ buffer pinning -- attribute-based or plain
VA, initial creation or resize -- goes through the same CQ-specific
helper.
qedr_init_user_queue(), mana_ib_create_queue(), get_mtt_entries()
(erdma), and hns_roce_mtr_create() are shared between CQ and other
callers (QP, SRQ, and for qedr/erdma/hns also MR), so each gains a new
is_cq parameter: true from the CQ call site, false from the others,
which must keep deriving direction from access flags rather than always
mapping DMA_FROM_DEVICE.
Also update bnxt_re_resize_cq()'s and qedr_init_user_queue()'s error
messages to name the new call instead of the old ib_umem_get_va().
vmw_pvrdma's pvrdma_create_cq() is deliberately NOT converted here.
Unlike every other driver checked, PVRDMA embeds a pvrdma_ring_state
producer/consumer header directly inside the same buffer as the CQEs
(cq->ring_state = cq->pdir.pages[0]), and the driver itself writes
cons_head back into it after polling (pvrdma_idx_ring_inc(&cq->ring_
state->rx.cons_head, ...)). That makes the buffer genuinely
bidirectional, not device-write/CPU-read-only like every other audited
driver's CQ. Forcing it onto ib_umem_get_cq_buf_or_va()'s hardcoded
DMA_FROM_DEVICE (added in the next commit) would break that CPU write.
PVRDMA's CQ stays on the generic ib_umem_get_va() path, where it already
passes IB_ACCESS_LOCAL_WRITE and so continues to correctly derive
DMA_BIDIRECTIONAL. See the dedicated vmw_pvrdma fix later in this series
for its QP and SRQ rings, which have the same embedded ring-state issue.
This is a pure refactor with no functional change: today
ib_umem_get_cq_buf_or_va() maps every buffer DMA_BIDIRECTIONAL, same as
ib_umem_get_va(). It prepares for the next commit, which changes
ib_umem_get_cq_buf_or_va() (and ib_umem_get_cq_buf()) to map CQ buffers
DMA_FROM_DEVICE -- once these call sites are already routed through it,
that change picks them all up automatically, with no follow-up gap to
close.
Signed-off-by: Yishai Hadas <yishaih@nvidia.com>
---
drivers/infiniband/hw/bnxt_re/ib_verbs.c | 9 ++++----
drivers/infiniband/hw/erdma/erdma_verbs.c | 17 +++++++++-----
drivers/infiniband/hw/hns/hns_roce_cq.c | 2 +-
drivers/infiniband/hw/hns/hns_roce_device.h | 2 +-
drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 2 +-
drivers/infiniband/hw/hns/hns_roce_mr.c | 22 +++++++++++++-----
drivers/infiniband/hw/hns/hns_roce_qp.c | 2 +-
drivers/infiniband/hw/hns/hns_roce_srq.c | 4 ++--
.../infiniband/hw/ionic/ionic_controlpath.c | 5 ++--
drivers/infiniband/hw/mana/cq.c | 2 +-
drivers/infiniband/hw/mana/main.c | 9 ++++++--
drivers/infiniband/hw/mana/mana_ib.h | 2 +-
drivers/infiniband/hw/mana/qp.c | 9 ++++----
drivers/infiniband/hw/mana/wq.c | 3 ++-
drivers/infiniband/hw/mlx4/cq.c | 14 ++++++-----
drivers/infiniband/hw/mlx5/cq.c | 6 ++---
drivers/infiniband/hw/qedr/verbs.c | 23 +++++++++++++------
17 files changed, 84 insertions(+), 49 deletions(-)
diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.c b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
index ccd2702db78b..e1197868c7a9 100644
--- a/drivers/infiniband/hw/bnxt_re/ib_verbs.c
+++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
@@ -3749,12 +3749,13 @@ int bnxt_re_resize_cq(struct ib_cq *ibcq, unsigned int cqe,
if (rc)
goto fail;
- cq->resize_umem = ib_umem_get_va(&rdev->ibdev, req.cq_va,
- entries * sizeof(struct cq_base),
- IB_ACCESS_LOCAL_WRITE);
+ cq->resize_umem = ib_umem_get_cq_buf_or_va(&rdev->ibdev, NULL,
+ 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_va failed! rc = %pe\n",
+ ibdev_err(&rdev->ibdev, "%s: ib_umem_get_cq_buf_or_va failed! rc = %pe\n",
__func__, cq->resize_umem);
cq->resize_umem = NULL;
goto fail;
diff --git a/drivers/infiniband/hw/erdma/erdma_verbs.c b/drivers/infiniband/hw/erdma/erdma_verbs.c
index fca2553e47ad..3519b5044e8f 100644
--- a/drivers/infiniband/hw/erdma/erdma_verbs.c
+++ b/drivers/infiniband/hw/erdma/erdma_verbs.c
@@ -828,11 +828,16 @@ static void erdma_destroy_mtt(struct erdma_dev *dev, struct erdma_mtt *mtt)
static int get_mtt_entries(struct erdma_dev *dev, struct erdma_mem *mem,
u64 start, u64 len, int access, u64 virt,
- unsigned long req_page_size, bool force_continuous)
+ unsigned long req_page_size, bool force_continuous,
+ bool is_cq)
{
int ret = 0;
- mem->umem = ib_umem_get_va(&dev->ibdev, start, len, access);
+ if (is_cq)
+ mem->umem = ib_umem_get_cq_buf_or_va(&dev->ibdev, NULL, start,
+ len, access);
+ else
+ mem->umem = ib_umem_get_va(&dev->ibdev, start, len, access);
if (IS_ERR(mem->umem)) {
ret = PTR_ERR(mem->umem);
mem->umem = NULL;
@@ -951,7 +956,7 @@ static int init_user_qp(struct erdma_qp *qp, struct erdma_ucontext *uctx,
ret = get_mtt_entries(qp->dev, &qp->user_qp.sq_mem, va,
qp->attrs.sq_size << SQEBB_SHIFT, 0, va,
- (SZ_1M - SZ_4K), true);
+ (SZ_1M - SZ_4K), true, false);
if (ret)
return ret;
@@ -960,7 +965,7 @@ static int init_user_qp(struct erdma_qp *qp, struct erdma_ucontext *uctx,
ret = get_mtt_entries(qp->dev, &qp->user_qp.rq_mem, va + rq_offset,
qp->attrs.rq_size << RQE_SHIFT, 0, va + rq_offset,
- (SZ_1M - SZ_4K), true);
+ (SZ_1M - SZ_4K), true, false);
if (ret)
goto put_sq_mtt;
@@ -1250,7 +1255,7 @@ struct ib_mr *erdma_reg_user_mr(struct ib_pd *ibpd, u64 start, u64 len,
return ERR_PTR(-ENOMEM);
ret = get_mtt_entries(dev, &mr->mem, start, len, access, virt,
- SZ_2G - SZ_4K, false);
+ SZ_2G - SZ_4K, false, false);
if (ret)
goto err_out_free;
@@ -1931,7 +1936,7 @@ static int erdma_init_user_cq(struct erdma_ucontext *ctx, struct erdma_cq *cq,
ret = get_mtt_entries(dev, &cq->user_cq.qbuf_mem, ureq->qbuf_va,
ureq->qbuf_len, IB_ACCESS_LOCAL_WRITE,
- ureq->qbuf_va, SZ_64M - SZ_4K, true);
+ ureq->qbuf_va, SZ_64M - SZ_4K, true, true);
if (ret)
return ret;
diff --git a/drivers/infiniband/hw/hns/hns_roce_cq.c b/drivers/infiniband/hw/hns/hns_roce_cq.c
index ae314f136732..7dfaa01cda67 100644
--- a/drivers/infiniband/hw/hns/hns_roce_cq.c
+++ b/drivers/infiniband/hw/hns/hns_roce_cq.c
@@ -265,7 +265,7 @@ static int alloc_cq_buf(struct hns_roce_dev *hr_dev, struct hns_roce_cq *hr_cq,
ret = hns_roce_mtr_create(hr_dev, &hr_cq->mtr, &buf_attr,
hr_dev->caps.cqe_ba_pg_sz + PAGE_SHIFT,
- udata, addr);
+ udata, addr, true);
if (ret)
ibdev_err(ibdev, "failed to alloc CQ mtr, ret = %d.\n", ret);
diff --git a/drivers/infiniband/hw/hns/hns_roce_device.h b/drivers/infiniband/hw/hns/hns_roce_device.h
index f4f899e87ea6..3accd77341ae 100644
--- a/drivers/infiniband/hw/hns/hns_roce_device.h
+++ b/drivers/infiniband/hw/hns/hns_roce_device.h
@@ -1232,7 +1232,7 @@ int hns_roce_mtr_find(struct hns_roce_dev *hr_dev, struct hns_roce_mtr *mtr,
int hns_roce_mtr_create(struct hns_roce_dev *hr_dev, struct hns_roce_mtr *mtr,
struct hns_roce_buf_attr *buf_attr,
unsigned int page_shift, struct ib_udata *udata,
- unsigned long user_addr);
+ unsigned long user_addr, bool is_cq);
void hns_roce_mtr_destroy(struct hns_roce_dev *hr_dev,
struct hns_roce_mtr *mtr);
int hns_roce_mtr_map(struct hns_roce_dev *hr_dev, struct hns_roce_mtr *mtr,
diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
index 368e1d74c283..b8177d054a31 100644
--- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
+++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
@@ -6919,7 +6919,7 @@ static int alloc_eq_buf(struct hns_roce_dev *hr_dev, struct hns_roce_eq *eq)
err = hns_roce_mtr_create(hr_dev, &eq->mtr, &buf_attr,
hr_dev->caps.eqe_ba_pg_sz + PAGE_SHIFT, NULL,
- 0);
+ 0, false);
if (err)
dev_err(hr_dev->dev, "failed to alloc EQE mtr, err %d\n", err);
diff --git a/drivers/infiniband/hw/hns/hns_roce_mr.c b/drivers/infiniband/hw/hns/hns_roce_mr.c
index 7d41ae897458..4799f667eeda 100644
--- a/drivers/infiniband/hw/hns/hns_roce_mr.c
+++ b/drivers/infiniband/hw/hns/hns_roce_mr.c
@@ -112,7 +112,7 @@ static int alloc_mr_pbl(struct hns_roce_dev *hr_dev, struct hns_roce_mr *mr,
err = hns_roce_mtr_create(hr_dev, &mr->pbl_mtr, &buf_attr,
hr_dev->caps.pbl_ba_pg_sz + PAGE_SHIFT,
- udata, start);
+ udata, start, false);
if (err) {
ibdev_err(ibdev, "failed to alloc pbl mtr, ret = %d.\n", err);
return err;
@@ -586,7 +586,8 @@ static void mtr_free_bufs(struct hns_roce_dev *hr_dev, struct hns_roce_mtr *mtr)
static int mtr_alloc_bufs(struct hns_roce_dev *hr_dev, struct hns_roce_mtr *mtr,
struct hns_roce_buf_attr *buf_attr,
- struct ib_udata *udata, unsigned long user_addr)
+ struct ib_udata *udata, unsigned long user_addr,
+ bool is_cq)
{
struct ib_device *ibdev = &hr_dev->ib_dev;
size_t total_size;
@@ -595,8 +596,14 @@ 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_va(ibdev, user_addr, total_size,
- buf_attr->user_access);
+ if (is_cq)
+ mtr->umem = ib_umem_get_cq_buf_or_va(ibdev, NULL,
+ user_addr,
+ total_size,
+ buf_attr->user_access);
+ else
+ 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);
@@ -1035,11 +1042,13 @@ static void mtr_free_mtt(struct hns_roce_dev *hr_dev, struct hns_roce_mtr *mtr)
* @ba_page_shift: page shift for multi-hop base address table
* @udata: user space context, if it's NULL, means kernel space
* @user_addr: userspace virtual address to start at
+ * @is_cq: true when @mtr backs a CQ buffer, which the device writes
+ * completion entries into
*/
int hns_roce_mtr_create(struct hns_roce_dev *hr_dev, struct hns_roce_mtr *mtr,
struct hns_roce_buf_attr *buf_attr,
unsigned int ba_page_shift, struct ib_udata *udata,
- unsigned long user_addr)
+ unsigned long user_addr, bool is_cq)
{
struct ib_device *ibdev = &hr_dev->ib_dev;
int ret;
@@ -1052,7 +1061,8 @@ int hns_roce_mtr_create(struct hns_roce_dev *hr_dev, struct hns_roce_mtr *mtr,
mtr->umem = NULL;
mtr->kmem = NULL;
} else {
- ret = mtr_alloc_bufs(hr_dev, mtr, buf_attr, udata, user_addr);
+ ret = mtr_alloc_bufs(hr_dev, mtr, buf_attr, udata, user_addr,
+ is_cq);
if (ret) {
ibdev_err(ibdev,
"failed to alloc mtr bufs, ret = %d.\n", ret);
diff --git a/drivers/infiniband/hw/hns/hns_roce_qp.c b/drivers/infiniband/hw/hns/hns_roce_qp.c
index e333a8c4acb5..c6c0dfdbdbc3 100644
--- a/drivers/infiniband/hw/hns/hns_roce_qp.c
+++ b/drivers/infiniband/hw/hns/hns_roce_qp.c
@@ -808,7 +808,7 @@ static int alloc_qp_buf(struct hns_roce_dev *hr_dev, struct hns_roce_qp *hr_qp,
}
ret = hns_roce_mtr_create(hr_dev, &hr_qp->mtr, &buf_attr,
PAGE_SHIFT + hr_dev->caps.mtt_ba_pg_sz,
- udata, addr);
+ udata, addr, false);
if (ret) {
ibdev_err(ibdev, "failed to create WQE mtr, ret = %d.\n", ret);
goto err_inline;
diff --git a/drivers/infiniband/hw/hns/hns_roce_srq.c b/drivers/infiniband/hw/hns/hns_roce_srq.c
index 4a54394f96be..b5e9ac9cfd59 100644
--- a/drivers/infiniband/hw/hns/hns_roce_srq.c
+++ b/drivers/infiniband/hw/hns/hns_roce_srq.c
@@ -180,7 +180,7 @@ static int alloc_srq_idx(struct hns_roce_dev *hr_dev, struct hns_roce_srq *srq,
ret = hns_roce_mtr_create(hr_dev, &idx_que->mtr, &buf_attr,
hr_dev->caps.idx_ba_pg_sz + PAGE_SHIFT,
- udata, addr);
+ udata, addr, false);
if (ret) {
ibdev_err(ibdev,
"failed to alloc SRQ idx mtr, ret = %d.\n", ret);
@@ -235,7 +235,7 @@ static int alloc_srq_wqe_buf(struct hns_roce_dev *hr_dev,
ret = hns_roce_mtr_create(hr_dev, &srq->buf_mtr, &buf_attr,
hr_dev->caps.srqwqe_ba_pg_sz + PAGE_SHIFT,
- udata, addr);
+ udata, addr, false);
if (ret)
ibdev_err(ibdev,
"failed to alloc SRQ buf mtr, ret = %d.\n", ret);
diff --git a/drivers/infiniband/hw/ionic/ionic_controlpath.c b/drivers/infiniband/hw/ionic/ionic_controlpath.c
index 37f71fb43811..f392c635338b 100644
--- a/drivers/infiniband/hw/ionic/ionic_controlpath.c
+++ b/drivers/infiniband/hw/ionic/ionic_controlpath.c
@@ -110,8 +110,9 @@ int ionic_create_cq_common(struct ionic_vcq *vcq,
if (rc)
goto err_qdesc;
- cq->umem = ib_umem_get_va(&dev->ibdev, req_cq->addr,
- req_cq->size, IB_ACCESS_LOCAL_WRITE);
+ cq->umem = ib_umem_get_cq_buf_or_va(&dev->ibdev, NULL,
+ req_cq->addr, req_cq->size,
+ IB_ACCESS_LOCAL_WRITE);
if (IS_ERR(cq->umem)) {
rc = PTR_ERR(cq->umem);
goto err_qdesc;
diff --git a/drivers/infiniband/hw/mana/cq.c b/drivers/infiniband/hw/mana/cq.c
index 6f9ac8b4aac8..de81a4b994e0 100644
--- a/drivers/infiniband/hw/mana/cq.c
+++ b/drivers/infiniband/hw/mana/cq.c
@@ -40,7 +40,7 @@ int mana_ib_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr,
cq->cqe = attr->cqe;
err = mana_ib_create_queue(mdev, ucmd.buf_addr, cq->cqe * COMP_ENTRY_SIZE,
- &cq->queue);
+ &cq->queue, true);
if (err) {
ibdev_dbg(ibdev, "Failed to create queue for create cq, %d\n", err);
return err;
diff --git a/drivers/infiniband/hw/mana/main.c b/drivers/infiniband/hw/mana/main.c
index 83a97f1c5caa..46cb51ea08b9 100644
--- a/drivers/infiniband/hw/mana/main.c
+++ b/drivers/infiniband/hw/mana/main.c
@@ -293,7 +293,7 @@ int mana_ib_create_kernel_queue(struct mana_ib_dev *mdev, u32 size, enum gdma_qu
}
int mana_ib_create_queue(struct mana_ib_dev *mdev, u64 addr, u32 size,
- struct mana_ib_queue *queue)
+ struct mana_ib_queue *queue, bool is_cq)
{
struct ib_umem *umem;
int err;
@@ -302,7 +302,12 @@ 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_va(&mdev->ib_dev, addr, size, IB_ACCESS_LOCAL_WRITE);
+ if (is_cq)
+ umem = ib_umem_get_cq_buf_or_va(&mdev->ib_dev, NULL, addr,
+ size, IB_ACCESS_LOCAL_WRITE);
+ else
+ 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/mana_ib.h b/drivers/infiniband/hw/mana/mana_ib.h
index 1be33ed8bd3b..fc71d0b7d57e 100644
--- a/drivers/infiniband/hw/mana/mana_ib.h
+++ b/drivers/infiniband/hw/mana/mana_ib.h
@@ -730,7 +730,7 @@ int mana_ib_gd_destroy_dma_region(struct mana_ib_dev *dev,
int mana_ib_create_kernel_queue(struct mana_ib_dev *mdev, u32 size, enum gdma_queue_type type,
struct mana_ib_queue *queue);
int mana_ib_create_queue(struct mana_ib_dev *mdev, u64 addr, u32 size,
- struct mana_ib_queue *queue);
+ struct mana_ib_queue *queue, bool is_cq);
void mana_ib_destroy_queue(struct mana_ib_dev *mdev, struct mana_ib_queue *queue);
struct ib_wq *mana_ib_create_wq(struct ib_pd *pd,
diff --git a/drivers/infiniband/hw/mana/qp.c b/drivers/infiniband/hw/mana/qp.c
index fac43b3a5eb7..88e792cb0f85 100644
--- a/drivers/infiniband/hw/mana/qp.c
+++ b/drivers/infiniband/hw/mana/qp.c
@@ -340,7 +340,8 @@ static int mana_ib_create_qp_raw(struct ib_qp *ibqp, struct ib_pd *ibpd,
ibdev_dbg(&mdev->ib_dev, "ucmd sq_buf_addr 0x%llx port %u\n",
ucmd.sq_buf_addr, ucmd.port);
- err = mana_ib_create_queue(mdev, ucmd.sq_buf_addr, ucmd.sq_buf_size, &qp->raw_sq);
+ err = mana_ib_create_queue(mdev, ucmd.sq_buf_addr, ucmd.sq_buf_size, &qp->raw_sq,
+ false);
if (err) {
ibdev_dbg(&mdev->ib_dev,
"Failed to create queue for create qp-raw, err %d\n", err);
@@ -579,7 +580,7 @@ static int mana_ib_create_rc_qp(struct ib_qp *ibqp, struct ib_pd *ibpd,
if (ucmd.comp_mask & MANA_IB_RC_MMQ_CREATE) {
flags &= ~MANA_RC_FLAG_NO_MMQ;
err = mana_ib_create_queue(mdev, ucmd.mmq_buf, ucmd.mmq_size,
- &qp->rc_qp.queues[i]);
+ &qp->rc_qp.queues[i], false);
if (err)
goto destroy_queues;
} else {
@@ -589,7 +590,7 @@ static int mana_ib_create_rc_qp(struct ib_qp *ibqp, struct ib_pd *ibpd,
continue;
}
err = mana_ib_create_queue(mdev, ucmd.queue_buf[j], ucmd.queue_size[j],
- &qp->rc_qp.queues[i]);
+ &qp->rc_qp.queues[i], false);
if (err)
goto destroy_queues;
j++;
@@ -663,7 +664,7 @@ static int mana_ib_create_uc_qp(struct ib_qp *ibqp, struct ib_pd *ibpd,
for (i = 0; i < MANA_UC_QUEUE_TYPE_MAX; ++i) {
err = mana_ib_create_queue(mdev, ucmd.queue_buf[i], ucmd.queue_size[i],
- &qp->uc_qp.queues[i]);
+ &qp->uc_qp.queues[i], false);
if (err)
goto destroy_queues;
}
diff --git a/drivers/infiniband/hw/mana/wq.c b/drivers/infiniband/hw/mana/wq.c
index 6b066d605dcb..4042f26632c0 100644
--- a/drivers/infiniband/hw/mana/wq.c
+++ b/drivers/infiniband/hw/mana/wq.c
@@ -25,7 +25,8 @@ struct ib_wq *mana_ib_create_wq(struct ib_pd *pd,
ibdev_dbg(&mdev->ib_dev, "ucmd wq_buf_addr 0x%llx\n", ucmd.wq_buf_addr);
- err = mana_ib_create_queue(mdev, ucmd.wq_buf_addr, ucmd.wq_buf_size, &wq->queue);
+ err = mana_ib_create_queue(mdev, ucmd.wq_buf_addr, ucmd.wq_buf_size, &wq->queue,
+ false);
if (err) {
ibdev_dbg(&mdev->ib_dev,
"Failed to create queue for create wq, %d\n", err);
diff --git a/drivers/infiniband/hw/mlx4/cq.c b/drivers/infiniband/hw/mlx4/cq.c
index 887912469742..74d1b07f9cc1 100644
--- a/drivers/infiniband/hw/mlx4/cq.c
+++ b/drivers/infiniband/hw/mlx4/cq.c
@@ -185,9 +185,10 @@ int mlx4_ib_create_user_cq(struct ib_cq *ibcq,
goto err_umem;
}
} else {
- cq->umem = ib_umem_get_va(&dev->ib_dev, ucmd.buf_addr,
- entries * cqe_size,
- IB_ACCESS_LOCAL_WRITE);
+ cq->umem = ib_umem_get_cq_buf_or_va(&dev->ib_dev, NULL,
+ ucmd.buf_addr,
+ entries * cqe_size,
+ IB_ACCESS_LOCAL_WRITE);
if (IS_ERR(cq->umem)) {
err = PTR_ERR(cq->umem);
goto err_cq;
@@ -354,9 +355,10 @@ 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_va(&dev->ib_dev, ucmd.buf_addr,
- entries * cqe_size,
- IB_ACCESS_LOCAL_WRITE);
+ cq->resize_umem = ib_umem_get_cq_buf_or_va(&dev->ib_dev, NULL,
+ 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/mlx5/cq.c b/drivers/infiniband/hw/mlx5/cq.c
index 49b4bf148a4a..ec4833c59c65 100644
--- a/drivers/infiniband/hw/mlx5/cq.c
+++ b/drivers/infiniband/hw/mlx5/cq.c
@@ -1245,9 +1245,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_va(&dev->ib_dev, ucmd.buf_addr,
- (size_t)ucmd.cqe_size * entries,
- IB_ACCESS_LOCAL_WRITE);
+ umem = ib_umem_get_cq_buf_or_va(&dev->ib_dev, NULL, 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/qedr/verbs.c b/drivers/infiniband/hw/qedr/verbs.c
index 012a0ab98d6b..4fecb90b1b8b 100644
--- a/drivers/infiniband/hw/qedr/verbs.c
+++ b/drivers/infiniband/hw/qedr/verbs.c
@@ -775,16 +775,23 @@ static inline int qedr_init_user_queue(struct ib_udata *udata,
struct qedr_userq *q, u64 buf_addr,
size_t buf_len, bool requires_db_rec,
int access,
- int alloc_and_init)
+ int alloc_and_init, bool is_cq)
{
u32 fw_pages;
int rc;
q->buf_addr = buf_addr;
q->buf_len = buf_len;
- q->umem = ib_umem_get_va(&dev->ibdev, q->buf_addr, q->buf_len, access);
+ if (is_cq)
+ q->umem = ib_umem_get_cq_buf_or_va(&dev->ibdev, NULL,
+ q->buf_addr, q->buf_len,
+ access);
+ else
+ 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_va, got %ld\n",
+ DP_ERR(dev, "create user queue: failed %s, got %ld\n",
+ is_cq ? "ib_umem_get_cq_buf_or_va" : "ib_umem_get_va",
PTR_ERR(q->umem));
return PTR_ERR(q->umem);
}
@@ -946,7 +953,7 @@ int qedr_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr,
rc = qedr_init_user_queue(udata, dev, &cq->q, ureq.addr,
ureq.len, true, IB_ACCESS_LOCAL_WRITE,
- 1);
+ 1, true);
if (rc)
goto err0;
@@ -1438,7 +1445,7 @@ static int qedr_init_srq_user_params(struct ib_udata *udata,
int rc;
rc = qedr_init_user_queue(udata, srq->dev, &srq->usrq, ureq->srq_addr,
- ureq->srq_len, false, access, 1);
+ ureq->srq_len, false, access, 1, false);
if (rc)
return rc;
@@ -1831,7 +1838,8 @@ static int qedr_create_user_qp(struct qedr_dev *dev,
if (qedr_qp_has_sq(qp)) {
/* SQ - read access only (0) */
rc = qedr_init_user_queue(udata, dev, &qp->usq, ureq.sq_addr,
- ureq.sq_len, true, 0, alloc_and_init);
+ ureq.sq_len, true, 0, alloc_and_init,
+ false);
if (rc)
return rc;
}
@@ -1839,7 +1847,8 @@ static int qedr_create_user_qp(struct qedr_dev *dev,
if (qedr_qp_has_rq(qp)) {
/* RQ - read access only (0) */
rc = qedr_init_user_queue(udata, dev, &qp->urq, ureq.rq_addr,
- ureq.rq_len, true, 0, alloc_and_init);
+ ureq.rq_len, true, 0, alloc_and_init,
+ false);
if (rc) {
ib_umem_release(qp->usq.umem);
qp->usq.umem = NULL;
--
2.18.1
next prev parent reply other threads:[~2026-09-08 15:30 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-08 15:28 [PATCH rdma-next 00/15] DMA direction and mlx5 driver correctness fixes Yishai Hadas
2026-09-08 15:28 ` [PATCH rdma-next 01/15] RDMA/erdma: Pin CQ buffer writable to match device DMA write access Yishai Hadas
2026-09-08 15:28 ` [PATCH rdma-next 02/15] RDMA/hns: " Yishai Hadas
2026-09-08 15:28 ` [PATCH rdma-next 03/15] RDMA/vmw_pvrdma: Pin QP and SRQ rings " Yishai Hadas
2026-09-08 15:28 ` Yishai Hadas [this message]
2026-09-08 15:28 ` [PATCH rdma-next 05/15] RDMA/umem: Support an explicit DMA direction other than DMA_BIDIRECTIONAL Yishai Hadas
2026-09-08 15:28 ` [PATCH rdma-next 06/15] RDMA/umem: Map CQ buffers DMA_FROM_DEVICE Yishai Hadas
2026-09-08 15:28 ` [PATCH rdma-next 07/15] RDMA/umem: Derive DMA direction from IB access flags Yishai Hadas
2026-09-08 15:28 ` [PATCH rdma-next 08/15] RDMA/mlx5: Fix mlx5_ib_dev_res_init() failure when XRC cap is absent Yishai Hadas
2026-09-08 15:28 ` [PATCH rdma-next 09/15] RDMA/mlx5: Put resource reference in mlx5_ib_wq_event() Yishai Hadas
2026-09-08 15:28 ` [PATCH rdma-next 10/15] RDMA/mlx5: Set WQ event handler before firmware RQ insertion Yishai Hadas
2026-09-08 15:28 ` [PATCH rdma-next 11/15] RDMA/mlx5: Set SRQ event handler before xarray insertion Yishai Hadas
2026-09-08 15:28 ` [PATCH rdma-next 12/15] RDMA/mlx5: Set RQ event handler for raw-packet QP Yishai Hadas
2026-09-08 15:28 ` [PATCH rdma-next 13/15] RDMA/mlx5: Set QP event handler before firmware QPC insertion Yishai Hadas
2026-09-08 15:28 ` [PATCH rdma-next 14/15] RDMA/mlx5: Initialize QP/RQ/SQ resource refcount before publishing it Yishai Hadas
2026-09-08 15:28 ` [PATCH rdma-next 15/15] RDMA/mlx5: Fix signed integer overflow in EQE qp_srq type shift Yishai Hadas
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260908152851.1307294-5-yishaih@nvidia.com \
--to=yishaih@nvidia.com \
--cc=abhijit.gangurde@amd.com \
--cc=allen.hubbe@amd.com \
--cc=bryan-bt.tan@broadcom.com \
--cc=chengyou@linux.alibaba.com \
--cc=huangjunxian6@hisilicon.com \
--cc=jgg@ziepe.ca \
--cc=kaishen@linux.alibaba.com \
--cc=kalesh-anakkur.purayil@broadcom.com \
--cc=kotaranov@microsoft.com \
--cc=leon@kernel.org \
--cc=linux-rdma@vger.kernel.org \
--cc=longli@microsoft.com \
--cc=maorg@nvidia.com \
--cc=mkalderon@marvell.com \
--cc=selvin.xavier@broadcom.com \
--cc=tangchengchang@huawei.com \
--cc=vishnu.dasa@broadcom.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox