From: Jiri Pirko Date: Fri, 29 May 2026 13:43:03 +0000 (+0200) Subject: RDMA/efa: Use ib_umem_get_cq_buf() for user CQ buffer X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e3433474db923168babdb5c83abb9e1af11a9e91;p=thirdparty%2Fkernel%2Flinux.git RDMA/efa: Use ib_umem_get_cq_buf() for user CQ buffer 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. Link: https://patch.msgid.link/r/20260529134312.2836341-8-jiri@resnulli.us Signed-off-by: Jiri Pirko Signed-off-by: Jason Gunthorpe --- diff --git a/drivers/infiniband/hw/efa/efa_verbs.c b/drivers/infiniband/hw/efa/efa_verbs.c index 8d97a837fa6ab..434d602359452 100644 --- a/drivers/infiniband/hw/efa/efa_verbs.c +++ b/drivers/infiniband/hw/efa/efa_verbs.c @@ -1049,6 +1049,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; } @@ -1101,6 +1102,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; @@ -1149,26 +1151,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, attrs, 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; } } @@ -1235,6 +1240,8 @@ err_free_mapped: 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;