]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
RDMA/efa: Use ib_umem_get_cq_buf() for user CQ buffer
authorJiri Pirko <jiri@nvidia.com>
Fri, 29 May 2026 13:43:03 +0000 (15:43 +0200)
committerJason Gunthorpe <jgg@nvidia.com>
Fri, 29 May 2026 23:19:58 +0000 (20:19 -0300)
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 <jiri@nvidia.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
drivers/infiniband/hw/efa/efa_verbs.c

index 8d97a837fa6ab24554dd5df85d9e2bb999b3ef2b..434d602359452707bbe90aa59b1aa35b28ae0025 100644 (file)
@@ -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;