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 {
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__ */
}
obj->rdev = rdev;
+ kref_init(&obj->usecnt);
uobj->object = obj;
uverbs_finalize_uobj_create(attrs, BNXT_RE_ALLOC_DBR_HANDLE);
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;
}