]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
RDMA/uverbs: Fix umem release in UVERBS_METHOD_CQ_CREATE
authorShuhao Fu <sfual@cse.ust.hk>
Fri, 10 Oct 2025 02:55:17 +0000 (10:55 +0800)
committerLeon Romanovsky <leon@kernel.org>
Sun, 19 Oct 2025 11:31:25 +0000 (07:31 -0400)
In `UVERBS_METHOD_CQ_CREATE`, umem should be released if anything goes
wrong. Currently, if `create_cq_umem` fails, umem would not be
released or referenced, causing a possible leak.

In this patch, we release umem at `UVERBS_METHOD_CQ_CREATE`, the driver
should not release umem if it returns an error code.

Fixes: 1a40c362ae26 ("RDMA/uverbs: Add a common way to create CQ with umem")
Signed-off-by: Shuhao Fu <sfual@cse.ust.hk>
Link: https://patch.msgid.link/aOh1le4YqtYwj-hH@osx.local
Signed-off-by: Leon Romanovsky <leon@kernel.org>
drivers/infiniband/core/uverbs_std_types_cq.c
drivers/infiniband/hw/efa/efa_verbs.c

index 37cd37556510406cb75457837b3f980e268a7982..fab5d914029dd76e51cbaa796dd2ac51b640d2cd 100644 (file)
@@ -206,6 +206,7 @@ static int UVERBS_HANDLER(UVERBS_METHOD_CQ_CREATE)(
        return ret;
 
 err_free:
+       ib_umem_release(umem);
        rdma_restrack_put(&cq->res);
        kfree(cq);
 err_event_file:
index d9a12681f84341c0baa8ef8b9e51d84a9008815f..22d3e25c3b9d118cbb3650fd8f270f4c347cf5c4 100644 (file)
@@ -1216,13 +1216,13 @@ int efa_create_cq_umem(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr,
                if (umem->length < cq->size) {
                        ibdev_dbg(&dev->ibdev, "External memory too small\n");
                        err = -EINVAL;
-                       goto err_free_mem;
+                       goto err_out;
                }
 
                if (!ib_umem_is_contiguous(umem)) {
                        ibdev_dbg(&dev->ibdev, "Non contiguous CQ unsupported\n");
                        err = -EINVAL;
-                       goto err_free_mem;
+                       goto err_out;
                }
 
                cq->cpu_addr = NULL;
@@ -1251,7 +1251,7 @@ int efa_create_cq_umem(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr,
 
        err = efa_com_create_cq(&dev->edev, &params, &result);
        if (err)
-               goto err_free_mem;
+               goto err_free_mapped;
 
        resp.db_off = result.db_off;
        resp.cq_idx = result.cq_idx;
@@ -1299,12 +1299,10 @@ err_remove_mmap:
        efa_cq_user_mmap_entries_remove(cq);
 err_destroy_cq:
        efa_destroy_cq_idx(dev, cq->cq_idx);
-err_free_mem:
-       if (umem)
-               ib_umem_release(umem);
-       else
-               efa_free_mapped(dev, cq->cpu_addr, cq->dma_addr, cq->size, DMA_FROM_DEVICE);
-
+err_free_mapped:
+       if (!umem)
+               efa_free_mapped(dev, cq->cpu_addr, cq->dma_addr, cq->size,
+                               DMA_FROM_DEVICE);
 err_out:
        atomic64_inc(&dev->stats.create_cq_err);
        return err;