From f60da09dbb152d7c8ee1719197d98149a8b0c017 Mon Sep 17 00:00:00 2001 From: Hans Petter Selasky Date: Wed, 16 Jun 2021 15:02:00 +0200 Subject: [PATCH] ibcore: Add some functions and definitions for selecting and querying retryable ucontext cleanup. Linux commit: 1c77483e4c50339b0306572167ccbff6b55d051b MFC after: 1 week Reviewed by: kib Sponsored by: Mellanox Technologies // NVIDIA Networking --- .../drivers/infiniband/core/ib_uverbs_cmd.c | 1 + sys/ofed/include/rdma/ib_verbs.h | 56 +++++++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/sys/ofed/drivers/infiniband/core/ib_uverbs_cmd.c b/sys/ofed/drivers/infiniband/core/ib_uverbs_cmd.c index ab6e27d40d3..df3f8657755 100644 --- a/sys/ofed/drivers/infiniband/core/ib_uverbs_cmd.c +++ b/sys/ofed/drivers/infiniband/core/ib_uverbs_cmd.c @@ -365,6 +365,7 @@ ssize_t ib_uverbs_get_context(struct ib_uverbs_file *file, ucontext->tgid = get_pid(task_pid_group_leader(current)); rcu_read_unlock(); ucontext->closing = 0; + ucontext->cleanup_retryable = false; #ifdef CONFIG_INFINIBAND_ON_DEMAND_PAGING ucontext->umem_tree = RB_ROOT; diff --git a/sys/ofed/include/rdma/ib_verbs.h b/sys/ofed/include/rdma/ib_verbs.h index 45a25dc06c4..723db4a659c 100644 --- a/sys/ofed/include/rdma/ib_verbs.h +++ b/sys/ofed/include/rdma/ib_verbs.h @@ -1364,6 +1364,20 @@ struct ib_fmr_attr { struct ib_umem; +enum rdma_remove_reason { + /* + * Userspace requested uobject deletion or initial try + * to remove uobject via cleanup. Call could fail + */ + RDMA_REMOVE_DESTROY, + /* Context deletion. This call should delete the actual object itself */ + RDMA_REMOVE_CLOSE, + /* Driver is being hot-unplugged. This call should delete the actual object itself */ + RDMA_REMOVE_DRIVER_REMOVE, + /* uobj is being cleaned-up before being committed */ + RDMA_REMOVE_ABORT, +}; + struct ib_ucontext { struct ib_device *device; struct list_head pd_list; @@ -1379,6 +1393,8 @@ struct ib_ucontext { struct list_head rwq_ind_tbl_list; int closing; + bool cleanup_retryable; + pid_t tgid; #ifdef CONFIG_INFINIBAND_ON_DEMAND_PAGING struct rb_root umem_tree; @@ -2213,6 +2229,46 @@ static inline bool ib_is_udata_cleared(struct ib_udata *udata, return ret; } +/** + * ib_is_destroy_retryable - Check whether the uobject destruction + * is retryable. + * @ret: The initial destruction return code + * @why: remove reason + * @uobj: The uobject that is destroyed + * + * This function is a helper function that IB layer and low-level drivers + * can use to consider whether the destruction of the given uobject is + * retry-able. + * It checks the original return code, if it wasn't success the destruction + * is retryable according to the ucontext state (i.e. cleanup_retryable) and + * the remove reason. (i.e. why). + * Must be called with the object locked for destroy. + */ +static inline bool ib_is_destroy_retryable(int ret, enum rdma_remove_reason why, + struct ib_uobject *uobj) +{ + return ret && (why == RDMA_REMOVE_DESTROY || + uobj->context->cleanup_retryable); +} + +/** + * ib_destroy_usecnt - Called during destruction to check the usecnt + * @usecnt: The usecnt atomic + * @why: remove reason + * @uobj: The uobject that is destroyed + * + * Non-zero usecnts will block destruction unless destruction was triggered by + * a ucontext cleanup. + */ +static inline int ib_destroy_usecnt(atomic_t *usecnt, + enum rdma_remove_reason why, + struct ib_uobject *uobj) +{ + if (atomic_read(usecnt) && ib_is_destroy_retryable(-EBUSY, why, uobj)) + return -EBUSY; + return 0; +} + /** * ib_modify_qp_is_ok - Check that the supplied attribute mask * contains all required attributes and no attributes not allowed for