]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
RDMA/bnxt_re: Avoid repeated requests to allocate WC pages
authorSelvin Xavier <selvin.xavier@broadcom.com>
Mon, 15 Jun 2026 22:47:47 +0000 (15:47 -0700)
committerJason Gunthorpe <jgg@nvidia.com>
Tue, 16 Jun 2026 17:30:40 +0000 (14:30 -0300)
Applications can request multiple WC pages for the same ucontext.
As of now, only 1 WC page per ucontext is supported. Add a lock to
avoid concurrent access and a check to fail repeated requests.
Also, if the mmap entry insert fails for the WC, free the Doorbell
page index mapped for the WC page.

Fixes: eee6268421a2 ("RDMA/bnxt_re: Move the UAPI methods to a dedicated file")
Fixes: 360da60d6c6e ("RDMA/bnxt_re: Enable low latency push")
Link: https://patch.msgid.link/r/20260615224751.232802-12-selvin.xavier@broadcom.com
Reviewed-by: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
Signed-off-by: Selvin Xavier <selvin.xavier@broadcom.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
drivers/infiniband/hw/bnxt_re/ib_verbs.c
drivers/infiniband/hw/bnxt_re/ib_verbs.h
drivers/infiniband/hw/bnxt_re/uapi.c

index c3570bf0204f43ae0f8145ba285a886227490095..565762529007637633aebe0f64810f3b05df2d12 100644 (file)
@@ -4770,6 +4770,7 @@ int bnxt_re_alloc_ucontext(struct ib_ucontext *ctx, struct ib_udata *udata)
                goto fail;
        }
        spin_lock_init(&uctx->sh_lock);
+       mutex_init(&uctx->wcdpi_lock);
 
        resp.comp_mask = BNXT_RE_UCNTX_CMASK_HAVE_CCTX;
        chip_met_rev_num = rdev->chip_ctx->chip_num;
index 4d6d1259a7956b2fdbdd1f7f8dbd627facc945fd..22bf81668cfb81004371943fac34c641c25a0c06 100644 (file)
@@ -143,6 +143,7 @@ struct bnxt_re_ucontext {
        struct bnxt_re_dev      *rdev;
        struct bnxt_qplib_dpi   dpi;
        struct bnxt_qplib_dpi   wcdpi;
+       struct mutex            wcdpi_lock;     /* serialises WC DPI alloc/free */
        void                    *shpg;
        spinlock_t              sh_lock;        /* protect shpg */
        struct rdma_user_mmap_entry *shpage_mmap;
index b9922360f11bc46eac7598ac1dc9adfdc2849b5b..7e5a55d2907674b7d4373057a35dd1380c21ec41 100644 (file)
@@ -98,14 +98,23 @@ static int UVERBS_HANDLER(BNXT_RE_METHOD_ALLOC_PAGE)(struct uverbs_attr_bundle *
 
        switch (alloc_type) {
        case BNXT_RE_ALLOC_WC_PAGE:
-               if (cctx->modes.db_push)  {
+               if (cctx->modes.db_push) {
+                       mutex_lock(&uctx->wcdpi_lock);
+                       /* already allocated — one WC page per context */
+                       if (uctx->wcdpi.dbr) {
+                               mutex_unlock(&uctx->wcdpi_lock);
+                               return -EEXIST;
+                       }
                        if (bnxt_qplib_alloc_dpi(&rdev->qplib_res, &uctx->wcdpi,
-                                                uctx, BNXT_QPLIB_DPI_TYPE_WC))
+                                                uctx, BNXT_QPLIB_DPI_TYPE_WC)) {
+                               mutex_unlock(&uctx->wcdpi_lock);
                                return -ENOMEM;
+                       }
                        length = PAGE_SIZE;
                        dpi = uctx->wcdpi.dpi;
                        addr = (u64)uctx->wcdpi.umdbr;
                        mmap_flag = BNXT_RE_MMAP_WC_DB;
+                       mutex_unlock(&uctx->wcdpi_lock);
                } else {
                        return -EINVAL;
                }
@@ -128,8 +137,15 @@ static int UVERBS_HANDLER(BNXT_RE_METHOD_ALLOC_PAGE)(struct uverbs_attr_bundle *
        }
 
        entry = bnxt_re_mmap_entry_insert(uctx, addr, mmap_flag, &mmap_offset);
-       if (!entry)
+       if (!entry) {
+               if (mmap_flag == BNXT_RE_MMAP_WC_DB) {
+                       mutex_lock(&uctx->wcdpi_lock);
+                       bnxt_qplib_dealloc_dpi(&rdev->qplib_res, &uctx->wcdpi);
+                       uctx->wcdpi.dbr = NULL;
+                       mutex_unlock(&uctx->wcdpi_lock);
+               }
                return -ENOMEM;
+       }
 
        uobj->object = entry;
        uverbs_finalize_uobj_create(attrs, BNXT_RE_ALLOC_PAGE_HANDLE);
@@ -160,11 +176,16 @@ static int alloc_page_obj_cleanup(struct ib_uobject *uobject,
 
        switch (entry->mmap_flag) {
        case BNXT_RE_MMAP_WC_DB:
-               if (uctx && uctx->wcdpi.dbr) {
+               if (uctx) {
                        struct bnxt_re_dev *rdev = uctx->rdev;
 
-                       bnxt_qplib_dealloc_dpi(&rdev->qplib_res, &uctx->wcdpi);
-                       uctx->wcdpi.dbr = NULL;
+                       mutex_lock(&uctx->wcdpi_lock);
+                       if (uctx->wcdpi.dbr) {
+                               bnxt_qplib_dealloc_dpi(&rdev->qplib_res,
+                                                      &uctx->wcdpi);
+                               uctx->wcdpi.dbr = NULL;
+                       }
+                       mutex_unlock(&uctx->wcdpi_lock);
                }
                break;
        case BNXT_RE_MMAP_DBR_BAR: