summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/infiniband/hw/bnxt_re/ib_verbs.c4
-rw-r--r--drivers/infiniband/hw/bnxt_re/ib_verbs.h2
-rw-r--r--drivers/infiniband/hw/bnxt_re/uapi.c13
3 files changed, 17 insertions, 2 deletions
diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.c b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
index e0c98b3ec298..c706ba19e719 100644
--- a/drivers/infiniband/hw/bnxt_re/ib_verbs.c
+++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
@@ -4943,6 +4943,10 @@ void bnxt_re_mmap_free(struct rdma_user_mmap_entry *rdma_entry)
bnxt_entry = container_of(rdma_entry, struct bnxt_re_user_mmap_entry,
rdma_entry);
+ if (bnxt_entry->dpi_valid)
+ bnxt_qplib_free_uc_dpi(&bnxt_entry->uctx->rdev->qplib_res,
+ &bnxt_entry->dpi);
+
kfree(bnxt_entry);
}
diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.h b/drivers/infiniband/hw/bnxt_re/ib_verbs.h
index 13dac48ed453..6a5bcc3fb289 100644
--- a/drivers/infiniband/hw/bnxt_re/ib_verbs.h
+++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.h
@@ -161,6 +161,8 @@ struct bnxt_re_user_mmap_entry {
struct bnxt_re_ucontext *uctx;
u64 mem_offset;
u8 mmap_flag;
+ bool dpi_valid;
+ struct bnxt_qplib_dpi dpi;
};
struct bnxt_re_dbr_obj {
diff --git a/drivers/infiniband/hw/bnxt_re/uapi.c b/drivers/infiniband/hw/bnxt_re/uapi.c
index b8fc8bfba2ad..1d44d6225da0 100644
--- a/drivers/infiniband/hw/bnxt_re/uapi.c
+++ b/drivers/infiniband/hw/bnxt_re/uapi.c
@@ -368,6 +368,13 @@ static int UVERBS_HANDLER(BNXT_RE_METHOD_DBR_ALLOC)(struct uverbs_attr_bundle *a
goto free_dpi;
}
+ /* Save DPI info to the mmap entry so that bnxt_re_mmap_free()
+ * can free the DPI slot only after the last reference to the
+ * mmap entry is released.
+ */
+ obj->entry->dpi = *dpi;
+ obj->entry->dpi_valid = true;
+
obj->rdev = rdev;
kref_init(&obj->usecnt);
uobj->object = obj;
@@ -396,10 +403,12 @@ 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;
+ /* Drop the driver's reference to the mmap entry (_remove()).
+ * The DPI slot gets freed from bnxt_re_mmap_free() only
+ * when there's no VMA mapping reference to it.
+ */
rdma_user_mmap_entry_remove(&obj->entry->rdma_entry);
- bnxt_qplib_free_uc_dpi(&rdev->qplib_res, &obj->dpi);
kfree(obj);
}