[PATCH v1 05/24] IB/core: ib_uobject need HW object reference count

Yuval Shaia
2019-08-21T14:22:34Z

From: Shamir Rabinovitch <shamir.rabinovitch@oracle.com>

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@oracle.com>
Signed-off-by: Shamir Rabinovitch <srabinov7@gmail.com>
---
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 7b429b2e7cf6..7e69866fc419 100644
--- a/include/rdma/ib_verbs.h
+++ b/include/rdma/ib_verbs.h
@@ -1496,6 +1496,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