From: Shamir Rabinovitch <shamir.rabinovitch@xxxxxxxxxx> This new refcnt will points to the refcnt member of the HW object and will behaves as expected by refcnt, i.e. will be increased and decreased as a result of usage changes and will destroy the object when reaches to zero. For a non-shared object refcnt will remain NULL. Signed-off-by: Shamir Rabinovitch <shamir.rabinovitch@xxxxxxxxxx> Signed-off-by: Shamir Rabinovitch <srabinov7@xxxxxxxxx> --- drivers/infiniband/core/rdma_core.c | 23 +++++++++++++++++++++-- include/rdma/ib_verbs.h | 7 +++++++ 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/drivers/infiniband/core/rdma_core.c b/drivers/infiniband/core/rdma_core.c index ccf4d069c25c..651625f632d7 100644 --- a/drivers/infiniband/core/rdma_core.c +++ b/drivers/infiniband/core/rdma_core.c @@ -516,7 +516,26 @@ static int __must_check destroy_hw_idr_uobject(struct ib_uobject *uobj, const struct uverbs_obj_idr_type *idr_type = container_of(uobj->uapi_object->type_attrs, struct uverbs_obj_idr_type, type); - int ret = idr_type->destroy_object(uobj, why, attrs); + static DEFINE_MUTEX(lock); + int ret, count; + + mutex_lock(&lock); + + if (uobj->refcnt) { + count = atomic_dec_return(uobj->refcnt); + WARN_ON(count < 0); /* use after free! */ + if (count) { + mutex_unlock(&lock); + goto skip; + } + } + + ret = idr_type->destroy_object(uobj, why, attrs); + + if (ret) + atomic_inc(uobj->refcnt); + + mutex_unlock(&lock); /* * We can only fail gracefully if the user requested to destroy the @@ -525,7 +544,7 @@ static int __must_check destroy_hw_idr_uobject(struct ib_uobject *uobj, */ if (ib_is_destroy_retryable(ret, why, uobj)) return ret; - +skip: if (why == RDMA_REMOVE_ABORT) return 0; diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h index 0900952d9b1f..d19c0394b05a 100644 --- a/include/rdma/ib_verbs.h +++ b/include/rdma/ib_verbs.h @@ -1444,6 +1444,13 @@ struct ib_uobject { struct rcu_head rcu; /* kfree_rcu() overhead */ const struct uverbs_api_object *uapi_object; + + /* + * ib_X HW object sharing support + * - NULL for HW objects that are not shareable + * - Pointer to ib_X reference counter for shareable HW objects + */ + atomic_t *refcnt; /* ib_X object ref count */ }; struct ib_udata { -- 2.20.1