summaryrefslogtreecommitdiffstats
path: root/include/rdma
diff options
context:
space:
mode:
authorJason Gunthorpe <jgg@mellanox.com>2018-07-25 21:40:12 -0600
committerJason Gunthorpe <jgg@mellanox.com>2018-08-01 14:55:48 -0600
commit87ad80abc70d2d5a4e383bc7e63867c9bc660838 (patch)
treeb45c48606a8240be4ecf6c8b971d0704a84fb290 /include/rdma
parent32ed5c00ac5fdea49058fd49bf8707e101dc3dfe (diff)
downloadlinux-stable-87ad80abc70d2d5a4e383bc7e63867c9bc660838.tar.gz
linux-stable-87ad80abc70d2d5a4e383bc7e63867c9bc660838.tar.bz2
linux-stable-87ad80abc70d2d5a4e383bc7e63867c9bc660838.zip
IB/uverbs: Consolidate uobject destruction
There are several flows that can destroy a uobject and each one is minimized and sprinkled throughout the code base, making it difficult to understand and very hard to modify the destroy path. Consolidate all of these into uverbs_destroy_uobject() and call it in all cases where a uobject has to be destroyed. This makes one change to the lifecycle, during any abort (eg when alloc_commit is not called) we always call out to alloc_abort, even if remove_commit needs to be called to delete a HW object. This also renames RDMA_REMOVE_DURING_CLEANUP to RDMA_REMOVE_ABORT to clarify its actual usage and revises some of the comments to reflect what the life cycle is for the type implementation. Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
Diffstat (limited to 'include/rdma')
-rw-r--r--include/rdma/ib_verbs.h4
-rw-r--r--include/rdma/uverbs_types.h70
2 files changed, 35 insertions, 39 deletions
diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h
index 1de8f0d2797c..be208421f7d3 100644
--- a/include/rdma/ib_verbs.h
+++ b/include/rdma/ib_verbs.h
@@ -1467,8 +1467,8 @@ enum rdma_remove_reason {
RDMA_REMOVE_CLOSE,
/* Driver is being hot-unplugged. This call should delete the actual object itself */
RDMA_REMOVE_DRIVER_REMOVE,
- /* Context is being cleaned-up, but commit was just completed */
- RDMA_REMOVE_DURING_CLEANUP,
+ /* uobj is being cleaned-up before being committed */
+ RDMA_REMOVE_ABORT,
};
struct ib_rdmacg_object {
diff --git a/include/rdma/uverbs_types.h b/include/rdma/uverbs_types.h
index 8bae28dd2e4f..875dd8c16ba3 100644
--- a/include/rdma/uverbs_types.h
+++ b/include/rdma/uverbs_types.h
@@ -38,53 +38,49 @@
struct uverbs_obj_type;
+/*
+ * The following sequences are valid:
+ * Success flow:
+ * alloc_begin
+ * alloc_commit
+ * [..]
+ * Access flow:
+ * lookup_get(exclusive=false) & uverbs_try_lock_object
+ * lookup_put(exclusive=false) via rdma_lookup_put_uobject
+ * Destruction flow:
+ * lookup_get(exclusive=true) & uverbs_try_lock_object
+ * remove_commit
+ * lookup_put(exclusive=true) via rdma_lookup_put_uobject
+ *
+ * Allocate Error flow #1
+ * alloc_begin
+ * alloc_abort
+ * Allocate Error flow #2
+ * alloc_begin
+ * remove_commit
+ * alloc_abort
+ * Allocate Error flow #3
+ * alloc_begin
+ * alloc_commit (fails)
+ * remove_commit
+ * alloc_abort
+ *
+ * In all cases the caller must hold the ufile kref until alloc_commit or
+ * alloc_abort returns.
+ */
struct uverbs_obj_type_class {
- /*
- * Get an ib_uobject that corresponds to the given id from ucontext,
- * These functions could create or destroy objects if required.
- * The action will be finalized only when commit, abort or put fops are
- * called.
- * The flow of the different actions is:
- * [alloc]: Starts with alloc_begin. The handlers logic is than
- * executed. If the handler is successful, alloc_commit
- * is called and the object is inserted to the repository.
- * Once alloc_commit completes the object is visible to
- * other threads and userspace.
- e Otherwise, alloc_abort is called and the object is
- * destroyed.
- * [lookup]: Starts with lookup_get which fetches and locks the
- * object. After the handler finished using the object, it
- * needs to call lookup_put to unlock it. The exclusive
- * flag indicates if the object is locked for exclusive
- * access.
- * [remove]: Starts with lookup_get with exclusive flag set. This
- * locks the object for exclusive access. If the handler
- * code completed successfully, remove_commit is called
- * and the ib_uobject is removed from the context's
- * uobjects repository and put. The object itself is
- * destroyed as well. Once remove succeeds new krefs to
- * the object cannot be acquired by other threads or
- * userspace and the hardware driver is removed from the
- * object. Other krefs on the object may still exist.
- * If the handler code failed, lookup_put should be
- * called. This callback is used when the context
- * is destroyed as well (process termination,
- * reset flow).
- */
struct ib_uobject *(*alloc_begin)(const struct uverbs_obj_type *type,
struct ib_uverbs_file *ufile);
+ /* This consumes the kref on uobj */
int (*alloc_commit)(struct ib_uobject *uobj);
+ /* This does not consume the kref on uobj */
void (*alloc_abort)(struct ib_uobject *uobj);
struct ib_uobject *(*lookup_get)(const struct uverbs_obj_type *type,
struct ib_uverbs_file *ufile, s64 id,
bool exclusive);
void (*lookup_put)(struct ib_uobject *uobj, bool exclusive);
- /*
- * Must be called with the exclusive lock held. If successful uobj is
- * invalid on return. On failure uobject is left completely
- * unchanged
- */
+ /* This does not consume the kref on uobj */
int __must_check (*remove_commit)(struct ib_uobject *uobj,
enum rdma_remove_reason why);
u8 needs_kfree_rcu;