From nobody Thu Apr 2 22:08:48 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 03B3B21D3D6; Fri, 13 Feb 2026 10:59:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770980351; cv=none; b=oL27bC4X4ea9zU3+mqSYlUawPXm0YH0H5np6SrXo3LN5sDiOuFchgHWdODr+3BFCuhz1tVd1Thw/xxB/q9jgLMguxUzaXpI34OprSYDuHWM175iJw6Xr5xkLZwQs5eYyxvJT9HSN+nRLQZQ+ZBeGt+h2QRq7kaU47AMTigjxzig= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770980351; c=relaxed/simple; bh=OblW+k4fZ/66WbbBaEPhF+RvNjNrCx26cYnmaaoJlyo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=X+6rz2iqHBPPs8FPOvX4esgcLv4/6SAvAV/QfeAkInPUXbYthVyoUAY5dA1qUbXgd56bZ89wKxSlKAXgNfViDJ991zWSaSwLB2ZzNIdY4Kv/QsxFh1AnvNnRv0xCAZZm07LOjMtjQYJv0VaIMVIX7ZwSkSeyrqTd4zTskEd/24c= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=VE9qRNFT; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="VE9qRNFT" Received: by smtp.kernel.org (Postfix) with ESMTPSA id C6717C4AF09; Fri, 13 Feb 2026 10:59:09 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1770980350; bh=OblW+k4fZ/66WbbBaEPhF+RvNjNrCx26cYnmaaoJlyo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=VE9qRNFTgKqNZxAWqgts3u0Oj9GyWzzwKwS4rb4Jyz/bmJ30iaFcg6mCBXZhUc9AV HYS3Z/jGKr9zLsCojzZWshilBKiJWjDWUoB4LQGVWWRXvWZlqliXEcWgMOTFTnVIry OvV5ks927WIWQsRPFQ873T7gi1TcO+tzHRTwPc1qrum6TYPAJ5Z4FDqvBn/9K0JCyx qwmaLcZSLgTzFvKZx3DVqk4achkA7mMAdzGO25DRdSRsS2/rbdm9EPlUbY6zOX6s/v ZIbIYSAXML5oEgPL5e9q1L0TmwCrS8EfInQ+AyR9gTRmvjge7ZQACl5b0ee7gYwNUi 70X+9g5zbgXBA== From: Leon Romanovsky To: Jason Gunthorpe , Leon Romanovsky , Selvin Xavier , Kalesh AP , Potnuri Bharat Teja , Michael Margolin , Gal Pressman , Yossi Leybovich , Cheng Xu , Kai Shen , Chengchang Tang , Junxian Huang , Abhijit Gangurde , Allen Hubbe , Krzysztof Czurylo , Tatyana Nikolova , Long Li , Konstantin Taranov , Yishai Hadas , Michal Kalderon , Bryan Tan , Vishnu Dasa , Broadcom internal kernel review list , Christian Benvenuti , Nelson Escobar , Dennis Dalessandro , Bernard Metzler , Zhu Yanjun Cc: linux-kernel@vger.kernel.org, linux-rdma@vger.kernel.org, linux-hyperv@vger.kernel.org Subject: [PATCH rdma-next 05/50] RDMA/core: Manage CQ umem in core code Date: Fri, 13 Feb 2026 12:57:41 +0200 Message-ID: <20260213-refactor-umem-v1-5-f3be85847922@nvidia.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260213-refactor-umem-v1-0-f3be85847922@nvidia.com> References: <20260213-refactor-umem-v1-0-f3be85847922@nvidia.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" X-Mailer: b4 0.15-dev-47773 Content-Transfer-Encoding: quoted-printable From: Leon Romanovsky 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. Signed-off-by: Leon Romanovsky --- drivers/infiniband/core/umem.c | 2 +- drivers/infiniband/core/uverbs_cmd.c | 1 + drivers/infiniband/core/uverbs_std_types_cq.c | 7 ++++++- drivers/infiniband/core/verbs.c | 2 ++ drivers/infiniband/hw/efa/efa_verbs.c | 24 +++++++++++------------- include/rdma/ib_verbs.h | 1 + 6 files changed, 22 insertions(+), 15 deletions(-) diff --git a/drivers/infiniband/core/umem.c b/drivers/infiniband/core/umem.c index 8137031c2a65..fc70b918f3f0 100644 --- a/drivers/infiniband/core/umem.c +++ b/drivers/infiniband/core/umem.c @@ -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)); diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core= /uverbs_cmd.c index f4616deeca54..fb19395b9f2a 100644 --- a/drivers/infiniband/core/uverbs_cmd.c +++ b/drivers/infiniband/core/uverbs_cmd.c @@ -1085,6 +1085,7 @@ static int create_cq(struct uverbs_attr_bundle *attrs, return uverbs_response(attrs, &resp, sizeof(resp)); =20 err_free: + ib_umem_release(cq->umem); rdma_restrack_put(&cq->res); kfree(cq); err_file: diff --git a/drivers/infiniband/core/uverbs_std_types_cq.c b/drivers/infini= band/core/uverbs_std_types_cq.c index fab5d914029d..05809f9ff0f6 100644 --- a/drivers/infiniband/core/uverbs_std_types_cq.c +++ b/drivers/infiniband/core/uverbs_std_types_cq.c @@ -186,6 +186,11 @@ static int UVERBS_HANDLER(UVERBS_METHOD_CQ_CREATE)( cq->comp_handler =3D ib_uverbs_comp_handler; cq->event_handler =3D ib_uverbs_cq_event_handler; cq->cq_context =3D 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 =3D umem; atomic_set(&cq->usecnt, 0); =20 rdma_restrack_new(&cq->res, RDMA_RESTRACK_CQ); @@ -206,7 +211,7 @@ static int UVERBS_HANDLER(UVERBS_METHOD_CQ_CREATE)( return ret; =20 err_free: - ib_umem_release(umem); + ib_umem_release(cq->umem); rdma_restrack_put(&cq->res); kfree(cq); err_event_file: diff --git a/drivers/infiniband/core/verbs.c b/drivers/infiniband/core/verb= s.c index 47a97797d7be..ad48d2458a3f 100644 --- a/drivers/infiniband/core/verbs.c +++ b/drivers/infiniband/core/verbs.c @@ -49,6 +49,7 @@ #include #include #include +#include #include #include =20 @@ -2249,6 +2250,7 @@ int ib_destroy_cq_user(struct ib_cq *cq, struct ib_ud= ata *udata) if (ret) return ret; =20 + ib_umem_release(cq->umem); rdma_restrack_del(&cq->res); kfree(cq); return ret; diff --git a/drivers/infiniband/hw/efa/efa_verbs.c b/drivers/infiniband/hw/= efa/efa_verbs.c index 19e3033d4ff7..ae9b98b4b528 100644 --- a/drivers/infiniband/hw/efa/efa_verbs.c +++ b/drivers/infiniband/hw/efa/efa_verbs.c @@ -1083,15 +1083,14 @@ int efa_destroy_cq(struct ib_cq *ibcq, struct ib_ud= ata *udata) cq->cq_idx, cq->cpu_addr, cq->size, &cq->dma_addr); =20 efa_destroy_cq_idx(dev, cq->cq_idx); - efa_cq_user_mmap_entries_remove(cq); + 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); } =20 - 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_DEVI= CE); return 0; } @@ -1212,22 +1211,20 @@ int efa_create_cq_umem(struct ib_cq *ibcq, const st= ruct ib_cq_init_attr *attr, cq->ucontext =3D ucontext; cq->size =3D PAGE_ALIGN(cmd.cq_entry_size * entries * cmd.num_sub_cqs); =20 - 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 =3D -EINVAL; goto err_out; } =20 - if (!ib_umem_is_contiguous(umem)) { + if (!ib_umem_is_contiguous(ibcq->umem)) { ibdev_dbg(&dev->ibdev, "Non contiguous CQ unsupported\n"); err =3D -EINVAL; goto err_out; } =20 - cq->cpu_addr =3D NULL; - cq->dma_addr =3D ib_umem_start_dma_addr(umem); - cq->umem =3D umem; + cq->dma_addr =3D ib_umem_start_dma_addr(ibcq->umem); } else { cq->cpu_addr =3D 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 stru= ct ib_cq_init_attr *attr, cq->ibcq.cqe =3D result.actual_depth; WARN_ON_ONCE(entries !=3D result.actual_depth); =20 - if (!umem) + if (cq->cpu_addr) err =3D cq_mmap_entries_setup(dev, cq, &resp, result.db_valid); =20 if (err) { @@ -1296,11 +1293,12 @@ int efa_create_cq_umem(struct ib_cq *ibcq, const st= ruct ib_cq_init_attr *attr, if (cq->eq) xa_erase(&dev->cqs_xa, cq->cq_idx); err_remove_mmap: - efa_cq_user_mmap_entries_remove(cq); + 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: diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h index e1ec5a6c74e6..b1e34fd2ed5f 100644 --- a/include/rdma/ib_verbs.h +++ b/include/rdma/ib_verbs.h @@ -1649,6 +1649,7 @@ struct ib_cq { u8 interrupt:1; u8 shared:1; unsigned int comp_vector; + struct ib_umem *umem; =20 /* * Implementation details of the RDMA core, don't use in drivers: --=20 2.52.0