]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
RDMA/bnxt_re: Enhance dbr usecnt logic in doorbell uapis
authorSriharsha Basavapatna <sriharsha.basavapatna@broadcom.com>
Tue, 19 May 2026 15:00:38 +0000 (20:30 +0530)
committerJason Gunthorpe <jgg@nvidia.com>
Sun, 24 May 2026 15:32:21 +0000 (12:32 -0300)
The current logic in the doorbell cleanup function is not
sufficient for a change in a subsequent patch, that fails
doorbell remove operation in some conditions. The cleanup
should facilitate freeing of the dbr object when the caller
may not retry the teardown operation (implicit teardown:
process-exit/driver-removal).

Extend this counter to use kref mechanism so that the dbr
object gets freed (via kref callback) when there are no more
references to it, rather than directly freeing it in the
cleanup uapi.

Link: https://patch.msgid.link/r/20260519150041.7251-7-sriharsha.basavapatna@broadcom.com
Signed-off-by: Sriharsha Basavapatna <sriharsha.basavapatna@broadcom.com>
Reviewed-by: Selvin Xavier <selvin.xavier@broadcom.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
drivers/infiniband/hw/bnxt_re/ib_verbs.h
drivers/infiniband/hw/bnxt_re/uapi.c

index 08f71a94d55d7bb0ae11929eafdcbbecb652b30c..13dac48ed453e820ec053cd32d71a57fd08591a1 100644 (file)
@@ -167,7 +167,7 @@ struct bnxt_re_dbr_obj {
        struct bnxt_re_dev *rdev;
        struct bnxt_qplib_dpi dpi;
        struct bnxt_re_user_mmap_entry *entry;
-       atomic_t usecnt; /* QPs using this dbr */
+       struct kref usecnt; /* 1 (uobject) + n (QPs using this dbr) */
 };
 
 struct bnxt_re_flow {
@@ -308,4 +308,5 @@ void bnxt_re_unlock_cqs(struct bnxt_re_qp *qp, unsigned long flags);
 struct bnxt_re_user_mmap_entry*
 bnxt_re_mmap_entry_insert(struct bnxt_re_ucontext *uctx, u64 mem_offset,
                          enum bnxt_re_mmap_flag mmap_flag, u64 *offset);
+void bnxt_re_dbr_kref_release(struct kref *ref);
 #endif /* __BNXT_RE_IB_VERBS_H__ */
index 3eaee7101615bf078c9b82dd88503f02410a8558..b8fc8bfba2ad456521131edee52ab8ab254e37eb 100644 (file)
@@ -369,6 +369,7 @@ static int UVERBS_HANDLER(BNXT_RE_METHOD_DBR_ALLOC)(struct uverbs_attr_bundle *a
        }
 
        obj->rdev = rdev;
+       kref_init(&obj->usecnt);
        uobj->object = obj;
        uverbs_finalize_uobj_create(attrs, BNXT_RE_ALLOC_DBR_HANDLE);
 
@@ -391,15 +392,24 @@ free_mem:
        return ret;
 }
 
+void bnxt_re_dbr_kref_release(struct kref *ref)
+{
+       struct bnxt_re_dbr_obj *obj =
+               container_of(ref, struct bnxt_re_dbr_obj, usecnt);
+       struct bnxt_re_dev *rdev = obj->rdev;
+
+       rdma_user_mmap_entry_remove(&obj->entry->rdma_entry);
+       bnxt_qplib_free_uc_dpi(&rdev->qplib_res, &obj->dpi);
+       kfree(obj);
+}
+
 static int bnxt_re_dbr_cleanup(struct ib_uobject *uobject,
                               enum rdma_remove_reason why,
                               struct uverbs_attr_bundle *attrs)
 {
        struct bnxt_re_dbr_obj *obj = uobject->object;
-       struct bnxt_re_dev *rdev = obj->rdev;
 
-       rdma_user_mmap_entry_remove(&obj->entry->rdma_entry);
-       bnxt_qplib_free_uc_dpi(&rdev->qplib_res, &obj->dpi);
+       kref_put(&obj->usecnt, bnxt_re_dbr_kref_release);
        return 0;
 }