]> git.ipfire.org Git - thirdparty/kernel/stable.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)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 24 Jul 2026 14:17:26 +0000 (16:17 +0200)
commit 441baa79043431807115fd030d7d0bb14ed441a0 upstream.

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>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/infiniband/hw/bnxt_re/ib_verbs.c
drivers/infiniband/hw/bnxt_re/ib_verbs.h
drivers/infiniband/hw/bnxt_re/uapi.c

index 8f380e9e41a8c8b3b90c83f691ae161fb0a5f495..25d88c2c5735f0b39f93f7088e856e8c8e9e4907 100644 (file)
@@ -4356,6 +4356,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 a11f56730a31c5b8cabd90df2ae3ba760c65b8d1..02b9c2e2d82b514f6b519d0aa58cc0131b319146 100644 (file)
@@ -142,6 +142,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 d93cafc5dfa0df9c88a4b089befcec6a3b940fca..ceec3fa0928ca5bc414fcdd92d2f78d69e7c7ca3 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;
                }
@@ -132,8 +141,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);
@@ -164,11 +180,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: