Commit 25c74104 authored by Leon Romanovsky's avatar Leon Romanovsky
Browse files

RDMA/core: Manage CQ umem in core code

In the current implementation, CQ umem is handled both by ib_core and
the driver. ib_core sometimes creates and destroys it, while the driver
also destroys it.

Store the umem in struct ib_cq and ensure that only ib_core manages
its lifetime, relying solely on its internal reference counter.

Link: https://patch.msgid.link/20260213-refactor-umem-v1-5-f3be85847922@nvidia.com


Signed-off-by: default avatarLeon Romanovsky <leonro@nvidia.com>
parent a731c862
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -283,7 +283,7 @@ EXPORT_SYMBOL(ib_umem_get);
 */
void ib_umem_release(struct ib_umem *umem)
{
	if (!umem)
	if (IS_ERR_OR_NULL(umem))
		return;
	if (umem->is_dmabuf)
		return ib_umem_dmabuf_release(to_ib_umem_dmabuf(umem));
+1 −0
Original line number Diff line number Diff line
@@ -1085,6 +1085,7 @@ static int create_cq(struct uverbs_attr_bundle *attrs,
	return uverbs_response(attrs, &resp, sizeof(resp));

err_free:
	ib_umem_release(cq->umem);
	rdma_restrack_put(&cq->res);
	kfree(cq);
err_file:
+6 −1
Original line number Diff line number Diff line
@@ -186,6 +186,11 @@ static int UVERBS_HANDLER(UVERBS_METHOD_CQ_CREATE)(
	cq->comp_handler  = ib_uverbs_comp_handler;
	cq->event_handler = ib_uverbs_cq_event_handler;
	cq->cq_context    = ev_file ? &ev_file->ev_queue : NULL;
	/*
	 * If UMEM is not provided here, legacy drivers will set it during
	 * CQ creation based on their internal udata.
	 */
	cq->umem = umem;
	atomic_set(&cq->usecnt, 0);

	rdma_restrack_new(&cq->res, RDMA_RESTRACK_CQ);
@@ -206,7 +211,7 @@ static int UVERBS_HANDLER(UVERBS_METHOD_CQ_CREATE)(
	return ret;

err_free:
	ib_umem_release(umem);
	ib_umem_release(cq->umem);
	rdma_restrack_put(&cq->res);
	kfree(cq);
err_event_file:
+2 −0
Original line number Diff line number Diff line
@@ -49,6 +49,7 @@
#include <rdma/ib_verbs.h>
#include <rdma/ib_cache.h>
#include <rdma/ib_addr.h>
#include <rdma/ib_umem.h>
#include <rdma/rw.h>
#include <rdma/lag.h>

@@ -2249,6 +2250,7 @@ int ib_destroy_cq_user(struct ib_cq *cq, struct ib_udata *udata)
	if (ret)
		return ret;

	ib_umem_release(cq->umem);
	rdma_restrack_del(&cq->res);
	kfree(cq);
	return ret;
+11 −13
Original line number Diff line number Diff line
@@ -1083,15 +1083,14 @@ int efa_destroy_cq(struct ib_cq *ibcq, struct ib_udata *udata)
		  cq->cq_idx, cq->cpu_addr, cq->size, &cq->dma_addr);

	efa_destroy_cq_idx(dev, cq->cq_idx);
	if (cq->cpu_addr)
		efa_cq_user_mmap_entries_remove(cq);
	if (cq->eq) {
		xa_erase(&dev->cqs_xa, cq->cq_idx);
		synchronize_irq(cq->eq->irq.irqn);
	}

	if (cq->umem)
		ib_umem_release(cq->umem);
	else
	if (cq->cpu_addr)
		efa_free_mapped(dev, cq->cpu_addr, cq->dma_addr, cq->size, DMA_FROM_DEVICE);
	return 0;
}
@@ -1212,22 +1211,20 @@ int efa_create_cq_umem(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 (umem) {
		if (umem->length < cq->size) {
	if (ibcq->umem) {
		if (ibcq->umem->length < cq->size) {
			ibdev_dbg(&dev->ibdev, "External memory too small\n");
			err = -EINVAL;
			goto err_out;
		}

		if (!ib_umem_is_contiguous(umem)) {
		if (!ib_umem_is_contiguous(ibcq->umem)) {
			ibdev_dbg(&dev->ibdev, "Non contiguous CQ unsupported\n");
			err = -EINVAL;
			goto err_out;
		}

		cq->cpu_addr = NULL;
		cq->dma_addr = ib_umem_start_dma_addr(umem);
		cq->umem = umem;
		cq->dma_addr = ib_umem_start_dma_addr(ibcq->umem);
	} else {
		cq->cpu_addr = efa_zalloc_mapped(dev, &cq->dma_addr, cq->size,
						 DMA_FROM_DEVICE);
@@ -1259,7 +1256,7 @@ int efa_create_cq_umem(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr,
	cq->ibcq.cqe = result.actual_depth;
	WARN_ON_ONCE(entries != result.actual_depth);

	if (!umem)
	if (cq->cpu_addr)
		err = cq_mmap_entries_setup(dev, cq, &resp, result.db_valid);

	if (err) {
@@ -1296,11 +1293,12 @@ int efa_create_cq_umem(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr,
	if (cq->eq)
		xa_erase(&dev->cqs_xa, cq->cq_idx);
err_remove_mmap:
	if (cq->cpu_addr)
		efa_cq_user_mmap_entries_remove(cq);
err_destroy_cq:
	efa_destroy_cq_idx(dev, cq->cq_idx);
err_free_mapped:
	if (!umem)
	if (cq->cpu_addr)
		efa_free_mapped(dev, cq->cpu_addr, cq->dma_addr, cq->size,
				DMA_FROM_DEVICE);
err_out:
Loading