Commit d8713158 authored by Shuhao Fu's avatar Shuhao Fu Committed by Leon Romanovsky
Browse files

RDMA/uverbs: Fix umem release in UVERBS_METHOD_CQ_CREATE



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: 1a40c362 ("RDMA/uverbs: Add a common way to create CQ with umem")
Signed-off-by: default avatarShuhao Fu <sfual@cse.ust.hk>
Link: https://patch.msgid.link/aOh1le4YqtYwj-hH@osx.local


Signed-off-by: default avatarLeon Romanovsky <leon@kernel.org>
parent 5575b764
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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:
+7 −9
Original line number Diff line number Diff line
@@ -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 @@ int efa_create_cq_umem(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr,
	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;