* [PATCH for-next v2 0/3] RDMA/erdma: Add DMA-BUF memory registration
@ 2026-05-18 12:06 Boshi Yu
2026-05-18 12:06 ` [PATCH for-next v2 1/3] RDMA/erdma: Rename get/put_mtt_entries to erdma_mem_init/uninit Boshi Yu
` (2 more replies)
0 siblings, 3 replies; 5+ messages in thread
From: Boshi Yu @ 2026-05-18 12:06 UTC (permalink / raw)
To: jgg, leon; +Cc: linux-rdma, chengyou, kaishen
Hi,
This patch series adds DMA-BUF memory registration support to the erdma
driver:
- #1 renames get/put_mtt_entries to erdma_mem_init/uninit to better reflect
their purpose of initializing the struct erdma_mem.
- #2 introduces struct erdma_mem_init_attr to pass parameters to
erdma_mem_init(), improving code maintainability and preparing for
DMA-BUF support.
- #3 implements erdma_reg_user_mr_dmabuf() to enable DMA-BUF based user
memory registration using ib_umem_dmabuf_get_pinned().
Thanks,
Boshi Yu
---
v2:
- Patch#2: Add validation for the return value of ib_umem_find_best_pgsz().
v1:
link: https://lore.kernel.org/all/20260507053437.46211-1-boshiyu@linux.alibaba.com/
Boshi Yu (3):
RDMA/erdma: Rename get/put_mtt_entries to erdma_mem_init/uninit
RDMA/erdma: Introduce struct erdma_mem_init_attr
RDMA/erdma: Implement erdma_reg_user_mr_dmabuf
drivers/infiniband/hw/erdma/erdma_main.c | 1 +
drivers/infiniband/hw/erdma/erdma_verbs.c | 152 +++++++++++++++-------
drivers/infiniband/hw/erdma/erdma_verbs.h | 19 +++
3 files changed, 123 insertions(+), 49 deletions(-)
--
2.46.0
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH for-next v2 1/3] RDMA/erdma: Rename get/put_mtt_entries to erdma_mem_init/uninit
2026-05-18 12:06 [PATCH for-next v2 0/3] RDMA/erdma: Add DMA-BUF memory registration Boshi Yu
@ 2026-05-18 12:06 ` Boshi Yu
2026-05-18 12:06 ` [PATCH for-next v2 2/3] RDMA/erdma: Introduce struct erdma_mem_init_attr Boshi Yu
2026-05-18 12:06 ` [PATCH for-next v2 3/3] RDMA/erdma: Implement erdma_reg_user_mr_dmabuf Boshi Yu
2 siblings, 0 replies; 5+ messages in thread
From: Boshi Yu @ 2026-05-18 12:06 UTC (permalink / raw)
To: jgg, leon; +Cc: linux-rdma, chengyou, kaishen
The get_mtt_entries() interface actually initializes the struct
erdma_mem. Rename the get_mtt_entries/put_mtt_entries to
erdma_mem_init/erdma_mem_uninit, respectively.
Reviewed-by: Cheng Xu <chengyou@linux.alibaba.com>
Signed-off-by: Boshi Yu <boshiyu@linux.alibaba.com>
---
drivers/infiniband/hw/erdma/erdma_verbs.c | 60 +++++++++++------------
1 file changed, 30 insertions(+), 30 deletions(-)
diff --git a/drivers/infiniband/hw/erdma/erdma_verbs.c b/drivers/infiniband/hw/erdma/erdma_verbs.c
index b59c2e3a5306..5ab66c9d8bdc 100644
--- a/drivers/infiniband/hw/erdma/erdma_verbs.c
+++ b/drivers/infiniband/hw/erdma/erdma_verbs.c
@@ -823,9 +823,9 @@ 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)
+static int erdma_mem_init(struct erdma_dev *dev, struct erdma_mem *mem,
+ u64 start, u64 len, int access, u64 virt,
+ unsigned long req_page_size, bool force_continuous)
{
int ret = 0;
@@ -862,7 +862,7 @@ static int get_mtt_entries(struct erdma_dev *dev, struct erdma_mem *mem,
return ret;
}
-static void put_mtt_entries(struct erdma_dev *dev, struct erdma_mem *mem)
+static void erdma_mem_uninit(struct erdma_dev *dev, struct erdma_mem *mem)
{
if (mem->mtt)
erdma_destroy_mtt(dev, mem->mtt);
@@ -946,45 +946,45 @@ static int init_user_qp(struct erdma_qp *qp, struct erdma_ucontext *uctx,
qp->attrs.rq_size * RQE_SIZE))
return -EINVAL;
- 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);
+ ret = erdma_mem_init(qp->dev, &qp->user_qp.sq_mem, va,
+ qp->attrs.sq_size << SQEBB_SHIFT, 0, va,
+ (SZ_1M - SZ_4K), true);
if (ret)
return ret;
rq_offset = ALIGN(qp->attrs.sq_size << SQEBB_SHIFT, ERDMA_HW_PAGE_SIZE);
qp->user_qp.rq_offset = rq_offset;
- ret = get_mtt_entries(qp->dev, &qp->user_qp.rq_mem, va + rq_offset,
+ ret = erdma_mem_init(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);
if (ret)
- goto put_sq_mtt;
+ goto uninit_sq_mem;
ret = erdma_map_user_dbrecords(uctx, dbrec_va,
&qp->user_qp.user_dbr_page,
&dbrec_dma);
if (ret)
- goto put_rq_mtt;
+ goto uninit_rq_mem;
qp->user_qp.sq_dbrec_dma = dbrec_dma;
qp->user_qp.rq_dbrec_dma = dbrec_dma + ERDMA_DB_SIZE;
return 0;
-put_rq_mtt:
- put_mtt_entries(qp->dev, &qp->user_qp.rq_mem);
+uninit_rq_mem:
+ erdma_mem_uninit(qp->dev, &qp->user_qp.rq_mem);
-put_sq_mtt:
- put_mtt_entries(qp->dev, &qp->user_qp.sq_mem);
+uninit_sq_mem:
+ erdma_mem_uninit(qp->dev, &qp->user_qp.sq_mem);
return ret;
}
static void free_user_qp(struct erdma_qp *qp, struct erdma_ucontext *uctx)
{
- put_mtt_entries(qp->dev, &qp->user_qp.sq_mem);
- put_mtt_entries(qp->dev, &qp->user_qp.rq_mem);
+ erdma_mem_uninit(qp->dev, &qp->user_qp.sq_mem);
+ erdma_mem_uninit(qp->dev, &qp->user_qp.rq_mem);
erdma_unmap_user_dbrecords(uctx, &qp->user_qp.user_dbr_page);
}
@@ -1246,14 +1246,14 @@ struct ib_mr *erdma_reg_user_mr(struct ib_pd *ibpd, u64 start, u64 len,
if (!mr)
return ERR_PTR(-ENOMEM);
- ret = get_mtt_entries(dev, &mr->mem, start, len, access, virt,
- SZ_2G - SZ_4K, false);
+ ret = erdma_mem_init(dev, &mr->mem, start, len, access, virt,
+ SZ_2G - SZ_4K, false);
if (ret)
goto err_out_free;
ret = erdma_create_stag(dev, &stag);
if (ret)
- goto err_out_put_mtt;
+ goto err_uninit_mem;
mr->ibmr.lkey = mr->ibmr.rkey = stag;
mr->ibmr.pd = ibpd;
@@ -1273,8 +1273,8 @@ struct ib_mr *erdma_reg_user_mr(struct ib_pd *ibpd, u64 start, u64 len,
erdma_free_idx(&dev->res_cb[ERDMA_RES_TYPE_STAG_IDX],
mr->ibmr.lkey >> 8);
-err_out_put_mtt:
- put_mtt_entries(dev, &mr->mem);
+err_uninit_mem:
+ erdma_mem_uninit(dev, &mr->mem);
err_out_free:
kfree(mr);
@@ -1304,7 +1304,7 @@ int erdma_dereg_mr(struct ib_mr *ibmr, struct ib_udata *udata)
erdma_free_idx(&dev->res_cb[ERDMA_RES_TYPE_STAG_IDX], ibmr->lkey >> 8);
- put_mtt_entries(dev, &mr->mem);
+ erdma_mem_uninit(dev, &mr->mem);
kfree(mr);
return 0;
@@ -1335,7 +1335,7 @@ int erdma_destroy_cq(struct ib_cq *ibcq, struct ib_udata *udata)
cq->kern_cq.dbrec_dma);
} else {
erdma_unmap_user_dbrecords(ctx, &cq->user_cq.user_dbr_page);
- put_mtt_entries(dev, &cq->user_cq.qbuf_mem);
+ erdma_mem_uninit(dev, &cq->user_cq.qbuf_mem);
}
xa_erase(&dev->cq_xa, cq->cqn);
@@ -1382,8 +1382,8 @@ int erdma_destroy_qp(struct ib_qp *ibqp, struct ib_udata *udata)
if (rdma_is_kernel_res(&qp->ibqp.res)) {
free_kernel_qp(qp);
} else {
- put_mtt_entries(dev, &qp->user_qp.sq_mem);
- put_mtt_entries(dev, &qp->user_qp.rq_mem);
+ erdma_mem_uninit(dev, &qp->user_qp.sq_mem);
+ erdma_mem_uninit(dev, &qp->user_qp.rq_mem);
erdma_unmap_user_dbrecords(ctx, &qp->user_qp.user_dbr_page);
}
@@ -1905,9 +1905,9 @@ static int erdma_init_user_cq(struct erdma_ucontext *ctx, struct erdma_cq *cq,
int ret;
struct erdma_dev *dev = to_edev(cq->ibcq.device);
- ret = get_mtt_entries(dev, &cq->user_cq.qbuf_mem, ureq->qbuf_va,
- ureq->qbuf_len, 0, ureq->qbuf_va, SZ_64M - SZ_4K,
- true);
+ ret = erdma_mem_init(dev, &cq->user_cq.qbuf_mem, ureq->qbuf_va,
+ ureq->qbuf_len, 0, ureq->qbuf_va, SZ_64M - SZ_4K,
+ true);
if (ret)
return ret;
@@ -1915,7 +1915,7 @@ static int erdma_init_user_cq(struct erdma_ucontext *ctx, struct erdma_cq *cq,
&cq->user_cq.user_dbr_page,
&cq->user_cq.dbrec_dma);
if (ret)
- put_mtt_entries(dev, &cq->user_cq.qbuf_mem);
+ erdma_mem_uninit(dev, &cq->user_cq.qbuf_mem);
return ret;
}
@@ -2006,7 +2006,7 @@ int erdma_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr,
err_free_res:
if (!rdma_is_kernel_res(&ibcq->res)) {
erdma_unmap_user_dbrecords(ctx, &cq->user_cq.user_dbr_page);
- put_mtt_entries(dev, &cq->user_cq.qbuf_mem);
+ erdma_mem_uninit(dev, &cq->user_cq.qbuf_mem);
} else {
dma_free_coherent(&dev->pdev->dev, depth << CQE_SHIFT,
cq->kern_cq.qbuf, cq->kern_cq.qbuf_dma_addr);
--
2.46.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH for-next v2 2/3] RDMA/erdma: Introduce struct erdma_mem_init_attr
2026-05-18 12:06 [PATCH for-next v2 0/3] RDMA/erdma: Add DMA-BUF memory registration Boshi Yu
2026-05-18 12:06 ` [PATCH for-next v2 1/3] RDMA/erdma: Rename get/put_mtt_entries to erdma_mem_init/uninit Boshi Yu
@ 2026-05-18 12:06 ` Boshi Yu
2026-05-18 12:06 ` [PATCH for-next v2 3/3] RDMA/erdma: Implement erdma_reg_user_mr_dmabuf Boshi Yu
2 siblings, 0 replies; 5+ messages in thread
From: Boshi Yu @ 2026-05-18 12:06 UTC (permalink / raw)
To: jgg, leon; +Cc: linux-rdma, chengyou, kaishen
Pass struct erdma_mem_init_attr to the erdma_mem_init() interface.
Additionally, validate the return value of ib_umem_find_best_pgsz().
Reviewed-by: Cheng Xu <chengyou@linux.alibaba.com>
Signed-off-by: Boshi Yu <boshiyu@linux.alibaba.com>
---
drivers/infiniband/hw/erdma/erdma_verbs.c | 63 +++++++++++++++--------
drivers/infiniband/hw/erdma/erdma_verbs.h | 13 +++++
2 files changed, 55 insertions(+), 21 deletions(-)
diff --git a/drivers/infiniband/hw/erdma/erdma_verbs.c b/drivers/infiniband/hw/erdma/erdma_verbs.c
index 5ab66c9d8bdc..7cfe0ce3c9c0 100644
--- a/drivers/infiniband/hw/erdma/erdma_verbs.c
+++ b/drivers/infiniband/hw/erdma/erdma_verbs.c
@@ -824,26 +824,33 @@ static void erdma_destroy_mtt(struct erdma_dev *dev, struct erdma_mtt *mtt)
}
static int erdma_mem_init(struct erdma_dev *dev, struct erdma_mem *mem,
- u64 start, u64 len, int access, u64 virt,
- unsigned long req_page_size, bool force_continuous)
+ struct erdma_mem_init_attr *attr)
{
int ret = 0;
- mem->umem = ib_umem_get(&dev->ibdev, start, len, access);
+ mem->umem =
+ ib_umem_get(&dev->ibdev, attr->start, attr->len, attr->access);
if (IS_ERR(mem->umem)) {
ret = PTR_ERR(mem->umem);
mem->umem = NULL;
return ret;
}
- mem->va = virt;
- mem->len = len;
- mem->page_size = ib_umem_find_best_pgsz(mem->umem, req_page_size, virt);
- mem->page_offset = start & (mem->page_size - 1);
+ mem->va = attr->virt;
+ mem->len = attr->len;
+
+ mem->page_size = ib_umem_find_best_pgsz(mem->umem, attr->req_page_size,
+ attr->virt);
+ if (!mem->page_size) {
+ ret = -EINVAL;
+ goto error_ret;
+ }
+
+ mem->page_offset = attr->start & (mem->page_size - 1);
mem->mtt_nents = ib_umem_num_dma_blocks(mem->umem, mem->page_size);
mem->page_cnt = mem->mtt_nents;
mem->mtt = erdma_create_mtt(dev, MTT_SIZE(mem->page_cnt),
- force_continuous);
+ attr->flags & ERDMA_MEM_FLAG_MTT_PHYS_CONT);
if (IS_ERR(mem->mtt)) {
ret = PTR_ERR(mem->mtt);
goto error_ret;
@@ -938,6 +945,7 @@ erdma_unmap_user_dbrecords(struct erdma_ucontext *ctx,
static int init_user_qp(struct erdma_qp *qp, struct erdma_ucontext *uctx,
u64 va, u32 len, u64 dbrec_va)
{
+ struct erdma_mem_init_attr attr = {};
dma_addr_t dbrec_dma;
u32 rq_offset;
int ret;
@@ -946,18 +954,22 @@ static int init_user_qp(struct erdma_qp *qp, struct erdma_ucontext *uctx,
qp->attrs.rq_size * RQE_SIZE))
return -EINVAL;
- ret = erdma_mem_init(qp->dev, &qp->user_qp.sq_mem, va,
- qp->attrs.sq_size << SQEBB_SHIFT, 0, va,
- (SZ_1M - SZ_4K), true);
+ attr.virt = va;
+ attr.start = va;
+ attr.req_page_size = SZ_1M - SZ_4K;
+ attr.len = qp->attrs.sq_size << SQEBB_SHIFT;
+ attr.flags = ERDMA_MEM_FLAG_MTT_PHYS_CONT;
+ ret = erdma_mem_init(qp->dev, &qp->user_qp.sq_mem, &attr);
if (ret)
return ret;
rq_offset = ALIGN(qp->attrs.sq_size << SQEBB_SHIFT, ERDMA_HW_PAGE_SIZE);
qp->user_qp.rq_offset = rq_offset;
- ret = erdma_mem_init(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);
+ attr.virt = va + rq_offset;
+ attr.start = va + rq_offset;
+ attr.len = qp->attrs.rq_size << RQE_SHIFT;
+ ret = erdma_mem_init(qp->dev, &qp->user_qp.rq_mem, &attr);
if (ret)
goto uninit_sq_mem;
@@ -1231,8 +1243,9 @@ struct ib_mr *erdma_reg_user_mr(struct ib_pd *ibpd, u64 start, u64 len,
u64 virt, int access, struct ib_dmah *dmah,
struct ib_udata *udata)
{
- struct erdma_mr *mr = NULL;
struct erdma_dev *dev = to_edev(ibpd->device);
+ struct erdma_mem_init_attr attr = {};
+ struct erdma_mr *mr = NULL;
u32 stag;
int ret;
@@ -1246,8 +1259,12 @@ struct ib_mr *erdma_reg_user_mr(struct ib_pd *ibpd, u64 start, u64 len,
if (!mr)
return ERR_PTR(-ENOMEM);
- ret = erdma_mem_init(dev, &mr->mem, start, len, access, virt,
- SZ_2G - SZ_4K, false);
+ attr.len = len;
+ attr.virt = virt;
+ attr.start = start;
+ attr.access = access;
+ attr.req_page_size = SZ_2G - SZ_4K;
+ ret = erdma_mem_init(dev, &mr->mem, &attr);
if (ret)
goto err_out_free;
@@ -1902,12 +1919,16 @@ int erdma_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *qp_attr,
static int erdma_init_user_cq(struct erdma_ucontext *ctx, struct erdma_cq *cq,
struct erdma_ureq_create_cq *ureq)
{
- int ret;
struct erdma_dev *dev = to_edev(cq->ibcq.device);
+ struct erdma_mem_init_attr attr = {};
+ int ret;
- ret = erdma_mem_init(dev, &cq->user_cq.qbuf_mem, ureq->qbuf_va,
- ureq->qbuf_len, 0, ureq->qbuf_va, SZ_64M - SZ_4K,
- true);
+ attr.len = ureq->qbuf_len;
+ attr.virt = ureq->qbuf_va;
+ attr.start = ureq->qbuf_va;
+ attr.req_page_size = SZ_64M - SZ_4K;
+ attr.flags = ERDMA_MEM_FLAG_MTT_PHYS_CONT;
+ ret = erdma_mem_init(dev, &cq->user_cq.qbuf_mem, &attr);
if (ret)
return ret;
diff --git a/drivers/infiniband/hw/erdma/erdma_verbs.h b/drivers/infiniband/hw/erdma/erdma_verbs.h
index 7d8d3fe501d5..79b3a90b03e7 100644
--- a/drivers/infiniband/hw/erdma/erdma_verbs.h
+++ b/drivers/infiniband/hw/erdma/erdma_verbs.h
@@ -108,6 +108,19 @@ struct erdma_mtt {
struct erdma_mtt *low_level;
};
+enum erdma_mem_flags {
+ ERDMA_MEM_FLAG_MTT_PHYS_CONT = (1 << 0),
+};
+
+struct erdma_mem_init_attr {
+ u64 start;
+ u64 virt;
+ u64 len;
+ unsigned long req_page_size;
+ int access;
+ u32 flags;
+};
+
struct erdma_mem {
struct ib_umem *umem;
struct erdma_mtt *mtt;
--
2.46.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH for-next v2 3/3] RDMA/erdma: Implement erdma_reg_user_mr_dmabuf
2026-05-18 12:06 [PATCH for-next v2 0/3] RDMA/erdma: Add DMA-BUF memory registration Boshi Yu
2026-05-18 12:06 ` [PATCH for-next v2 1/3] RDMA/erdma: Rename get/put_mtt_entries to erdma_mem_init/uninit Boshi Yu
2026-05-18 12:06 ` [PATCH for-next v2 2/3] RDMA/erdma: Introduce struct erdma_mem_init_attr Boshi Yu
@ 2026-05-18 12:06 ` Boshi Yu
2026-05-25 16:37 ` Jason Gunthorpe
2 siblings, 1 reply; 5+ messages in thread
From: Boshi Yu @ 2026-05-18 12:06 UTC (permalink / raw)
To: jgg, leon; +Cc: linux-rdma, chengyou, kaishen
Support DMA-BUF based user memory registration by adding the
erdma_reg_user_mr_dmabuf() callback. We refactor the existing
erdma_reg_user_mr() into a common _erdma_reg_user_mr() function
that handles both regular and DMA-BUF memory registration.
Reviewed-by: Cheng Xu <chengyou@linux.alibaba.com>
Signed-off-by: Boshi Yu <boshiyu@linux.alibaba.com>
---
drivers/infiniband/hw/erdma/erdma_main.c | 1 +
drivers/infiniband/hw/erdma/erdma_verbs.c | 55 ++++++++++++++++++-----
drivers/infiniband/hw/erdma/erdma_verbs.h | 6 +++
3 files changed, 51 insertions(+), 11 deletions(-)
diff --git a/drivers/infiniband/hw/erdma/erdma_main.c b/drivers/infiniband/hw/erdma/erdma_main.c
index 7e87a815e853..6e4860428e5b 100644
--- a/drivers/infiniband/hw/erdma/erdma_main.c
+++ b/drivers/infiniband/hw/erdma/erdma_main.c
@@ -526,6 +526,7 @@ static const struct ib_device_ops erdma_device_ops = {
.query_qp = erdma_query_qp,
.req_notify_cq = erdma_req_notify_cq,
.reg_user_mr = erdma_reg_user_mr,
+ .reg_user_mr_dmabuf = erdma_reg_user_mr_dmabuf,
.modify_qp = erdma_modify_qp,
INIT_RDMA_OBJ_SIZE(ib_cq, erdma_cq, ibcq),
diff --git a/drivers/infiniband/hw/erdma/erdma_verbs.c b/drivers/infiniband/hw/erdma/erdma_verbs.c
index 7cfe0ce3c9c0..995cc208cdd7 100644
--- a/drivers/infiniband/hw/erdma/erdma_verbs.c
+++ b/drivers/infiniband/hw/erdma/erdma_verbs.c
@@ -826,14 +826,27 @@ static void erdma_destroy_mtt(struct erdma_dev *dev, struct erdma_mtt *mtt)
static int erdma_mem_init(struct erdma_dev *dev, struct erdma_mem *mem,
struct erdma_mem_init_attr *attr)
{
+ struct ib_umem_dmabuf *umem_dmabuf;
int ret = 0;
- mem->umem =
- ib_umem_get(&dev->ibdev, attr->start, attr->len, attr->access);
- if (IS_ERR(mem->umem)) {
- ret = PTR_ERR(mem->umem);
- mem->umem = NULL;
- return ret;
+ if (attr->flags & ERDMA_MEM_FLAG_DMABUF) {
+ umem_dmabuf = ib_umem_dmabuf_get_pinned(&dev->ibdev,
+ attr->start, attr->len,
+ attr->fd, attr->access);
+ if (IS_ERR(umem_dmabuf)) {
+ ret = PTR_ERR(umem_dmabuf);
+ mem->umem = NULL;
+ return ret;
+ }
+ mem->umem = &umem_dmabuf->umem;
+ } else {
+ mem->umem = ib_umem_get(&dev->ibdev, attr->start, attr->len,
+ attr->access);
+ if (IS_ERR(mem->umem)) {
+ ret = PTR_ERR(mem->umem);
+ mem->umem = NULL;
+ return ret;
+ }
}
mem->va = attr->virt;
@@ -1239,9 +1252,10 @@ int erdma_map_mr_sg(struct ib_mr *ibmr, struct scatterlist *sg, int sg_nents,
return num;
}
-struct ib_mr *erdma_reg_user_mr(struct ib_pd *ibpd, u64 start, u64 len,
- u64 virt, int access, struct ib_dmah *dmah,
- struct ib_udata *udata)
+static struct ib_mr *
+_erdma_reg_user_mr(struct ib_pd *ibpd, struct ib_udata *udata,
+ struct ib_dmah *dmah, u64 start, u64 len, u64 virt,
+ int access, int fd, bool dmabuf)
{
struct erdma_dev *dev = to_edev(ibpd->device);
struct erdma_mem_init_attr attr = {};
@@ -1259,6 +1273,10 @@ struct ib_mr *erdma_reg_user_mr(struct ib_pd *ibpd, u64 start, u64 len,
if (!mr)
return ERR_PTR(-ENOMEM);
+ if (dmabuf)
+ attr.flags |= ERDMA_MEM_FLAG_DMABUF;
+
+ attr.fd = fd;
attr.len = len;
attr.virt = virt;
attr.start = start;
@@ -1274,8 +1292,6 @@ struct ib_mr *erdma_reg_user_mr(struct ib_pd *ibpd, u64 start, u64 len,
mr->ibmr.lkey = mr->ibmr.rkey = stag;
mr->ibmr.pd = ibpd;
- mr->mem.va = virt;
- mr->mem.len = len;
mr->access = ERDMA_MR_ACC_LR | to_erdma_access_flags(access);
mr->valid = 1;
mr->type = ERDMA_MR_TYPE_NORMAL;
@@ -1299,6 +1315,23 @@ struct ib_mr *erdma_reg_user_mr(struct ib_pd *ibpd, u64 start, u64 len,
return ERR_PTR(ret);
}
+struct ib_mr *erdma_reg_user_mr(struct ib_pd *ibpd, u64 start, u64 len,
+ u64 virt, int access, struct ib_dmah *dmah,
+ struct ib_udata *udata)
+{
+ return _erdma_reg_user_mr(ibpd, udata, dmah, start, len, virt, access,
+ 0, false);
+}
+
+struct ib_mr *erdma_reg_user_mr_dmabuf(struct ib_pd *ibpd, u64 start, u64 len,
+ u64 virt, int fd, int access,
+ struct ib_dmah *dmah,
+ struct uverbs_attr_bundle *attrs)
+{
+ return _erdma_reg_user_mr(ibpd, &attrs->driver_udata, dmah, start, len,
+ virt, access, fd, true);
+}
+
int erdma_dereg_mr(struct ib_mr *ibmr, struct ib_udata *udata)
{
struct erdma_mr *mr;
diff --git a/drivers/infiniband/hw/erdma/erdma_verbs.h b/drivers/infiniband/hw/erdma/erdma_verbs.h
index 79b3a90b03e7..15bdad8b14ce 100644
--- a/drivers/infiniband/hw/erdma/erdma_verbs.h
+++ b/drivers/infiniband/hw/erdma/erdma_verbs.h
@@ -110,6 +110,7 @@ struct erdma_mtt {
enum erdma_mem_flags {
ERDMA_MEM_FLAG_MTT_PHYS_CONT = (1 << 0),
+ ERDMA_MEM_FLAG_DMABUF = (1 << 1),
};
struct erdma_mem_init_attr {
@@ -118,6 +119,7 @@ struct erdma_mem_init_attr {
u64 len;
unsigned long req_page_size;
int access;
+ int fd;
u32 flags;
};
@@ -467,6 +469,10 @@ int erdma_req_notify_cq(struct ib_cq *ibcq, enum ib_cq_notify_flags flags);
struct ib_mr *erdma_reg_user_mr(struct ib_pd *ibpd, u64 start, u64 len,
u64 virt, int access, struct ib_dmah *dmah,
struct ib_udata *udata);
+struct ib_mr *erdma_reg_user_mr_dmabuf(struct ib_pd *ibpd, u64 start, u64 len,
+ u64 virt, int fd, int access,
+ struct ib_dmah *dmah,
+ struct uverbs_attr_bundle *attrs);
struct ib_mr *erdma_get_dma_mr(struct ib_pd *ibpd, int rights);
int erdma_dereg_mr(struct ib_mr *ibmr, struct ib_udata *data);
int erdma_mmap(struct ib_ucontext *ctx, struct vm_area_struct *vma);
--
2.46.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH for-next v2 3/3] RDMA/erdma: Implement erdma_reg_user_mr_dmabuf
2026-05-18 12:06 ` [PATCH for-next v2 3/3] RDMA/erdma: Implement erdma_reg_user_mr_dmabuf Boshi Yu
@ 2026-05-25 16:37 ` Jason Gunthorpe
0 siblings, 0 replies; 5+ messages in thread
From: Jason Gunthorpe @ 2026-05-25 16:37 UTC (permalink / raw)
To: Boshi Yu; +Cc: leon, linux-rdma, chengyou, kaishen
On Mon, May 18, 2026 at 08:06:28PM +0800, Boshi Yu wrote:
> + if (attr->flags & ERDMA_MEM_FLAG_DMABUF) {
> + umem_dmabuf = ib_umem_dmabuf_get_pinned(&dev->ibdev,
> + attr->start, attr->len,
> + attr->fd, attr->access);
> + if (IS_ERR(umem_dmabuf)) {
I don't want to see new MR implementations that use the get_pinned
interface.
Please implement the revoked interface Jacob added:
commit ff85a2ebacbdaec9f28c4660c991295ace93cd1c
Author: Jacob Moroni <jmoroni@google.com>
Date: Thu Mar 5 17:08:24 2026 +0000
RDMA/umem: Add pinned revocable dmabuf import interface
Added an interface for importing a pinned but revocable dmabuf.
This interface can be used by drivers that are capable of revocation
so that they can import dmabufs from exporters that may require it,
such as VFIO.
Any IBTA compliant device should be implement revoke at least through
regreg_mr.
Jason
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-05-25 16:37 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-18 12:06 [PATCH for-next v2 0/3] RDMA/erdma: Add DMA-BUF memory registration Boshi Yu
2026-05-18 12:06 ` [PATCH for-next v2 1/3] RDMA/erdma: Rename get/put_mtt_entries to erdma_mem_init/uninit Boshi Yu
2026-05-18 12:06 ` [PATCH for-next v2 2/3] RDMA/erdma: Introduce struct erdma_mem_init_attr Boshi Yu
2026-05-18 12:06 ` [PATCH for-next v2 3/3] RDMA/erdma: Implement erdma_reg_user_mr_dmabuf Boshi Yu
2026-05-25 16:37 ` Jason Gunthorpe
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox