From nobody Thu Apr 2 22:12:32 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 104D8354AEC; Fri, 13 Feb 2026 11:00:26 +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=1770980427; cv=none; b=lkOZH4juwgGEAJYcKxSAY4MoPau93zg0253O0v6nSrJ8acZNOo8L2lT/y8iXOnDDSysNn8AXfCIf+BIM6y+wNcWf/ZPSsaP1uHgTgZ0n+C3GDe0qK43GloYzHw6nWshUQklggpy7lDaFIVFc6rO6HHNAut5uPwLyfNbcdBUYWWs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770980427; c=relaxed/simple; bh=ie+0JBki2/glNSETQLy2aDTa3dexDvCcQEZRepXCc4s=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=IbiCR9Vbt/I5V9H7R9wY1UPKqPJ+uuRya9GRgaf7EsbcHRfYjHe/ub7/2rLjcUNwiRKE2V+ls7HOV1vr5DKGf4CLvowa4/5ccvabC1uwLt+ROXZokakEqW7qTLdVtOZofez6YJp5nVTH8nUd07GFbpesiwQvAjFTn/MyCcB7KDk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Z60BlmFK; 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="Z60BlmFK" Received: by smtp.kernel.org (Postfix) with ESMTPSA id AE252C116C6; Fri, 13 Feb 2026 11:00:25 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1770980426; bh=ie+0JBki2/glNSETQLy2aDTa3dexDvCcQEZRepXCc4s=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Z60BlmFKZA9KLWlKIWXibTo03BEI4Znra/QFK5qLMmskd3vMcQO/KSDf0M6cjr+UL 4879MvwQ7Rx3shHZT3TgbusodoiXCOWwMPV2uhdCM56aST0UBZ3RpGUdmAWsL3KqNJ OUR0SJn3g3a1jjGl+k+Ts+jJyPfwnymUDiswuNq5MyW3eezF2FTz1VpnGCqmg5UL9k xkr3JHLTq45C4lO78eb/0XYlfB8eTzbyfbiR4bA0WCr63b5gB/wZOBxqmwcjuO9Isc BmBgPnY5VqJaM2yhdmsSMRWD/yt4gLqSOox4oq392oFf+u8W8oNeWlk4S9hkXruRO+ HrxYW+//q5Svg== 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 25/50] RDMA/mana: Provide a modern CQ creation interface Date: Fri, 13 Feb 2026 12:58:01 +0200 Message-ID: <20260213-refactor-umem-v1-25-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 The uverbs CQ creation UAPI allows users to supply their own umem for a CQ. Update mana to support this workflow while preserving support for creating umem through the legacy interface. Signed-off-by: Leon Romanovsky --- drivers/infiniband/hw/mana/cq.c | 128 +++++++++++++++++++++++--------= ---- drivers/infiniband/hw/mana/device.c | 1 + drivers/infiniband/hw/mana/main.c | 25 +++---- drivers/infiniband/hw/mana/mana_ib.h | 4 +- drivers/infiniband/hw/mana/qp.c | 42 ++++++++++-- drivers/infiniband/hw/mana/wq.c | 14 +++- 6 files changed, 147 insertions(+), 67 deletions(-) diff --git a/drivers/infiniband/hw/mana/cq.c b/drivers/infiniband/hw/mana/c= q.c index 2dce1b677115..605122ecf9f9 100644 --- a/drivers/infiniband/hw/mana/cq.c +++ b/drivers/infiniband/hw/mana/cq.c @@ -5,8 +5,8 @@ =20 #include "mana_ib.h" =20 -int mana_ib_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *at= tr, - struct uverbs_attr_bundle *attrs) +int mana_ib_create_user_cq(struct ib_cq *ibcq, const struct ib_cq_init_att= r *attr, + struct uverbs_attr_bundle *attrs) { struct ib_udata *udata =3D &attrs->driver_udata; struct mana_ib_cq *cq =3D container_of(ibcq, struct mana_ib_cq, ibcq); @@ -17,7 +17,6 @@ int mana_ib_create_cq(struct ib_cq *ibcq, const struct ib= _cq_init_attr *attr, struct mana_ib_dev *mdev; bool is_rnic_cq; u32 doorbell; - u32 buf_size; int err; =20 mdev =3D container_of(ibdev, struct mana_ib_dev, ib_dev); @@ -26,44 +25,100 @@ int mana_ib_create_cq(struct ib_cq *ibcq, const struct= ib_cq_init_attr *attr, cq->cq_handle =3D INVALID_MANA_HANDLE; is_rnic_cq =3D mana_ib_is_rnic(mdev); =20 - if (udata) { - if (udata->inlen < offsetof(struct mana_ib_create_cq, flags)) - return -EINVAL; + if (udata->inlen < offsetof(struct mana_ib_create_cq, flags)) + return -EINVAL; =20 - err =3D ib_copy_from_udata(&ucmd, udata, min(sizeof(ucmd), udata->inlen)= ); - if (err) { - ibdev_dbg(ibdev, "Failed to copy from udata for create cq, %d\n", err); - return err; - } + err =3D ib_copy_from_udata(&ucmd, udata, min(sizeof(ucmd), udata->inlen)); + if (err) { + ibdev_dbg(ibdev, "Failed to copy from udata for create cq, %d\n", err); + return err; + } =20 - if ((!is_rnic_cq && attr->cqe > mdev->adapter_caps.max_qp_wr) || - attr->cqe > U32_MAX / COMP_ENTRY_SIZE) { - ibdev_dbg(ibdev, "CQE %d exceeding limit\n", attr->cqe); - return -EINVAL; - } + if ((!is_rnic_cq && attr->cqe > mdev->adapter_caps.max_qp_wr) || + attr->cqe > U32_MAX / COMP_ENTRY_SIZE) { + ibdev_dbg(ibdev, "CQE %d exceeding limit\n", attr->cqe); + return -EINVAL; + } + + cq->cqe =3D attr->cqe; + if (!ibcq->umem) + ibcq->umem =3D ib_umem_get(ibdev, ucmd.buf_addr, + cq->cqe * COMP_ENTRY_SIZE, + IB_ACCESS_LOCAL_WRITE); + if (IS_ERR(ibcq->umem)) + return PTR_ERR(ibcq->umem); + cq->queue.umem =3D ibcq->umem; + + err =3D mana_ib_create_queue(mdev, &cq->queue); + if (err) + return err; =20 - cq->cqe =3D attr->cqe; - err =3D mana_ib_create_queue(mdev, ucmd.buf_addr, cq->cqe * COMP_ENTRY_S= IZE, - &cq->queue); + mana_ucontext =3D rdma_udata_to_drv_context(udata, struct mana_ib_ucontex= t, + ibucontext); + doorbell =3D mana_ucontext->doorbell; + + if (is_rnic_cq) { + err =3D mana_ib_gd_create_cq(mdev, cq, doorbell); if (err) { - ibdev_dbg(ibdev, "Failed to create queue for create cq, %d\n", err); - return err; + ibdev_dbg(ibdev, "Failed to create RNIC cq, %d\n", err); + goto err_destroy_queue; } =20 - mana_ucontext =3D rdma_udata_to_drv_context(udata, struct mana_ib_uconte= xt, - ibucontext); - doorbell =3D mana_ucontext->doorbell; - } else { - buf_size =3D MANA_PAGE_ALIGN(roundup_pow_of_two(attr->cqe * COMP_ENTRY_S= IZE)); - cq->cqe =3D buf_size / COMP_ENTRY_SIZE; - err =3D mana_ib_create_kernel_queue(mdev, buf_size, GDMA_CQ, &cq->queue); + err =3D mana_ib_install_cq_cb(mdev, cq); if (err) { - ibdev_dbg(ibdev, "Failed to create kernel queue for create cq, %d\n", e= rr); - return err; + ibdev_dbg(ibdev, "Failed to install cq callback, %d\n", err); + goto err_destroy_rnic_cq; } - doorbell =3D mdev->gdma_dev->doorbell; } =20 + resp.cqid =3D cq->queue.id; + err =3D ib_copy_to_udata(udata, &resp, min(sizeof(resp), udata->outlen)); + if (err) { + ibdev_dbg(&mdev->ib_dev, "Failed to copy to udata, %d\n", err); + goto err_remove_cq_cb; + } + + spin_lock_init(&cq->cq_lock); + INIT_LIST_HEAD(&cq->list_send_qp); + INIT_LIST_HEAD(&cq->list_recv_qp); + + return 0; + +err_remove_cq_cb: + mana_ib_remove_cq_cb(mdev, cq); +err_destroy_rnic_cq: + mana_ib_gd_destroy_cq(mdev, cq); +err_destroy_queue: + mana_ib_destroy_queue(mdev, &cq->queue); + return err; +} + +int mana_ib_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *at= tr, + struct uverbs_attr_bundle *attrs) +{ + struct mana_ib_cq *cq =3D container_of(ibcq, struct mana_ib_cq, ibcq); + struct ib_device *ibdev =3D ibcq->device; + struct mana_ib_dev *mdev; + bool is_rnic_cq; + u32 doorbell; + u32 buf_size; + int err; + + mdev =3D container_of(ibdev, struct mana_ib_dev, ib_dev); + + cq->comp_vector =3D attr->comp_vector % ibdev->num_comp_vectors; + cq->cq_handle =3D INVALID_MANA_HANDLE; + is_rnic_cq =3D mana_ib_is_rnic(mdev); + + buf_size =3D MANA_PAGE_ALIGN(roundup_pow_of_two(attr->cqe * COMP_ENTRY_SI= ZE)); + cq->cqe =3D buf_size / COMP_ENTRY_SIZE; + err =3D mana_ib_create_kernel_queue(mdev, buf_size, GDMA_CQ, &cq->queue); + if (err) { + ibdev_dbg(ibdev, "Failed to create kernel queue for create cq, %d\n", er= r); + return err; + } + doorbell =3D mdev->gdma_dev->doorbell; + if (is_rnic_cq) { err =3D mana_ib_gd_create_cq(mdev, cq, doorbell); if (err) { @@ -78,23 +133,12 @@ int mana_ib_create_cq(struct ib_cq *ibcq, const struct= ib_cq_init_attr *attr, } } =20 - if (udata) { - resp.cqid =3D cq->queue.id; - err =3D ib_copy_to_udata(udata, &resp, min(sizeof(resp), udata->outlen)); - if (err) { - ibdev_dbg(&mdev->ib_dev, "Failed to copy to udata, %d\n", err); - goto err_remove_cq_cb; - } - } - spin_lock_init(&cq->cq_lock); INIT_LIST_HEAD(&cq->list_send_qp); INIT_LIST_HEAD(&cq->list_recv_qp); =20 return 0; =20 -err_remove_cq_cb: - mana_ib_remove_cq_cb(mdev, cq); err_destroy_rnic_cq: mana_ib_gd_destroy_cq(mdev, cq); err_destroy_queue: diff --git a/drivers/infiniband/hw/mana/device.c b/drivers/infiniband/hw/ma= na/device.c index ccc2279ca63c..c5c5fe051424 100644 --- a/drivers/infiniband/hw/mana/device.c +++ b/drivers/infiniband/hw/mana/device.c @@ -21,6 +21,7 @@ static const struct ib_device_ops mana_ib_dev_ops =3D { .alloc_ucontext =3D mana_ib_alloc_ucontext, .create_ah =3D mana_ib_create_ah, .create_cq =3D mana_ib_create_cq, + .create_user_cq =3D mana_ib_create_user_cq, .create_qp =3D mana_ib_create_qp, .create_rwq_ind_table =3D mana_ib_create_rwq_ind_table, .create_wq =3D mana_ib_create_wq, diff --git a/drivers/infiniband/hw/mana/main.c b/drivers/infiniband/hw/mana= /main.c index fac159f7128d..a871b8287dc9 100644 --- a/drivers/infiniband/hw/mana/main.c +++ b/drivers/infiniband/hw/mana/main.c @@ -261,35 +261,26 @@ int mana_ib_create_kernel_queue(struct mana_ib_dev *m= dev, u32 size, enum gdma_qu return 0; } =20 -int mana_ib_create_queue(struct mana_ib_dev *mdev, u64 addr, u32 size, +int mana_ib_create_queue(struct mana_ib_dev *mdev, struct mana_ib_queue *queue) { - struct ib_umem *umem; int err; =20 - queue->umem =3D NULL; queue->id =3D INVALID_QUEUE_ID; queue->gdma_region =3D GDMA_INVALID_DMA_REGION; =20 - umem =3D ib_umem_get(&mdev->ib_dev, addr, size, IB_ACCESS_LOCAL_WRITE); - if (IS_ERR(umem)) { - ibdev_dbg(&mdev->ib_dev, "Failed to get umem, %pe\n", umem); - return PTR_ERR(umem); - } - - err =3D mana_ib_create_zero_offset_dma_region(mdev, umem, &queue->gdma_re= gion); + err =3D mana_ib_create_zero_offset_dma_region(mdev, queue->umem, + &queue->gdma_region); if (err) { - ibdev_dbg(&mdev->ib_dev, "Failed to create dma region, %d\n", err); - goto free_umem; + ibdev_dbg(&mdev->ib_dev, "Failed to create dma region, %d\n", + err); + return err; } - queue->umem =3D umem; =20 - ibdev_dbg(&mdev->ib_dev, "created dma region 0x%llx\n", queue->gdma_regio= n); + ibdev_dbg(&mdev->ib_dev, "created dma region 0x%llx\n", + queue->gdma_region); =20 return 0; -free_umem: - ib_umem_release(umem); - return err; } =20 void mana_ib_destroy_queue(struct mana_ib_dev *mdev, struct mana_ib_queue = *queue) diff --git a/drivers/infiniband/hw/mana/mana_ib.h b/drivers/infiniband/hw/m= ana/mana_ib.h index a7c8c0fd7019..3bc7c88dc136 100644 --- a/drivers/infiniband/hw/mana/mana_ib.h +++ b/drivers/infiniband/hw/mana/mana_ib.h @@ -624,7 +624,7 @@ int mana_ib_gd_destroy_dma_region(struct mana_ib_dev *d= ev, =20 int mana_ib_create_kernel_queue(struct mana_ib_dev *mdev, u32 size, enum g= dma_queue_type type, struct mana_ib_queue *queue); -int mana_ib_create_queue(struct mana_ib_dev *mdev, u64 addr, u32 size, +int mana_ib_create_queue(struct mana_ib_dev *mdev, struct mana_ib_queue *queue); void mana_ib_destroy_queue(struct mana_ib_dev *mdev, struct mana_ib_queue = *queue); =20 @@ -667,6 +667,8 @@ void mana_ib_uncfg_vport(struct mana_ib_dev *dev, struc= t mana_ib_pd *pd, =20 int mana_ib_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *at= tr, struct uverbs_attr_bundle *attrs); +int mana_ib_create_user_cq(struct ib_cq *ibcq, const struct ib_cq_init_att= r *attr, + struct uverbs_attr_bundle *attrs); =20 int mana_ib_destroy_cq(struct ib_cq *ibcq, struct ib_udata *udata); =20 diff --git a/drivers/infiniband/hw/mana/qp.c b/drivers/infiniband/hw/mana/q= p.c index 48c1f4977f21..b08dbc675741 100644 --- a/drivers/infiniband/hw/mana/qp.c +++ b/drivers/infiniband/hw/mana/qp.c @@ -326,11 +326,20 @@ static int mana_ib_create_qp_raw(struct ib_qp *ibqp, = struct ib_pd *ibpd, ibdev_dbg(&mdev->ib_dev, "ucmd sq_buf_addr 0x%llx port %u\n", ucmd.sq_buf_addr, ucmd.port); =20 - err =3D mana_ib_create_queue(mdev, ucmd.sq_buf_addr, ucmd.sq_buf_size, &q= p->raw_sq); + qp->raw_sq.umem =3D ib_umem_get(&mdev->ib_dev, ucmd.sq_buf_addr, + ucmd.sq_buf_size, IB_ACCESS_LOCAL_WRITE); + if (IS_ERR(qp->raw_sq.umem)) { + err =3D PTR_ERR(qp->raw_sq.umem); + ibdev_dbg(&mdev->ib_dev, + "Failed to get umem for qp-raw, err %d\n", err); + goto err_free_vport; + } + + err =3D mana_ib_create_queue(mdev, &qp->raw_sq); if (err) { ibdev_dbg(&mdev->ib_dev, "Failed to create queue for create qp-raw, err %d\n", err); - goto err_free_vport; + goto err_release_umem; } =20 /* Create a WQ on the same port handle used by the Ethernet */ @@ -391,6 +400,10 @@ static int mana_ib_create_qp_raw(struct ib_qp *ibqp, s= truct ib_pd *ibpd, =20 err_destroy_queue: mana_ib_destroy_queue(mdev, &qp->raw_sq); + return err; + +err_release_umem: + ib_umem_release(qp->raw_sq.umem); =20 err_free_vport: mana_ib_uncfg_vport(mdev, pd, port); @@ -553,13 +566,25 @@ static int mana_ib_create_rc_qp(struct ib_qp *ibqp, s= truct ib_pd *ibpd, if (i =3D=3D MANA_RC_SEND_QUEUE_FMR) { qp->rc_qp.queues[i].id =3D INVALID_QUEUE_ID; qp->rc_qp.queues[i].gdma_region =3D GDMA_INVALID_DMA_REGION; + qp->rc_qp.queues[i].umem =3D NULL; continue; } - err =3D mana_ib_create_queue(mdev, ucmd.queue_buf[j], ucmd.queue_size[j], - &qp->rc_qp.queues[i]); + qp->rc_qp.queues[i].umem =3D ib_umem_get(&mdev->ib_dev, + ucmd.queue_buf[j], + ucmd.queue_size[j], + IB_ACCESS_LOCAL_WRITE); + if (IS_ERR(qp->rc_qp.queues[i].umem)) { + err =3D PTR_ERR(qp->rc_qp.queues[i].umem); + ibdev_err(&mdev->ib_dev, "Failed to get umem for queue %d, err %d\n", + i, err); + goto release_umems; + } + + err =3D mana_ib_create_queue(mdev, &qp->rc_qp.queues[i]); if (err) { ibdev_err(&mdev->ib_dev, "Failed to create queue %d, err %d\n", i, err); - goto destroy_queues; + ib_umem_release(qp->rc_qp.queues[i].umem); + goto release_umems; } j++; } @@ -598,6 +623,13 @@ static int mana_ib_create_rc_qp(struct ib_qp *ibqp, st= ruct ib_pd *ibpd, while (i-- > 0) mana_ib_destroy_queue(mdev, &qp->rc_qp.queues[i]); return err; + +release_umems: + while (i-- > 0) { + if (i !=3D MANA_RC_SEND_QUEUE_FMR) + ib_umem_release(qp->rc_qp.queues[i].umem); + } + return err; } =20 static void mana_add_qp_to_cqs(struct mana_ib_qp *qp) diff --git a/drivers/infiniband/hw/mana/wq.c b/drivers/infiniband/hw/mana/w= q.c index f959f4b9244f..be474aa8bdfc 100644 --- a/drivers/infiniband/hw/mana/wq.c +++ b/drivers/infiniband/hw/mana/wq.c @@ -31,11 +31,19 @@ struct ib_wq *mana_ib_create_wq(struct ib_pd *pd, =20 ibdev_dbg(&mdev->ib_dev, "ucmd wq_buf_addr 0x%llx\n", ucmd.wq_buf_addr); =20 - err =3D mana_ib_create_queue(mdev, ucmd.wq_buf_addr, ucmd.wq_buf_size, &w= q->queue); + wq->queue.umem =3D ib_umem_get(&mdev->ib_dev, ucmd.wq_buf_addr, + ucmd.wq_buf_size, IB_ACCESS_LOCAL_WRITE); + if (IS_ERR(wq->queue.umem)) { + err =3D PTR_ERR(wq->queue.umem); + ibdev_dbg(&mdev->ib_dev, "Failed to get umem for create wq, %d\n", err); + goto err_free_wq; + } + + err =3D mana_ib_create_queue(mdev, &wq->queue); if (err) { ibdev_dbg(&mdev->ib_dev, "Failed to create queue for create wq, %d\n", err); - goto err_free_wq; + goto err_release_umem; } =20 wq->wqe =3D init_attr->max_wr; @@ -43,6 +51,8 @@ struct ib_wq *mana_ib_create_wq(struct ib_pd *pd, wq->rx_object =3D INVALID_MANA_HANDLE; return &wq->ibwq; =20 +err_release_umem: + ib_umem_release(wq->queue.umem); err_free_wq: kfree(wq); =20 --=20 2.52.0