From 6ef1c82821b2ae9bfa26fe65e6f0a66dfd79b7d7 Mon Sep 17 00:00:00 2001 From: Jason Gunthorpe Date: Wed, 4 Jul 2018 11:32:08 +0300 Subject: [PATCH] IB/uverbs: Replace ib_ucontext with ib_uverbs_file in core function calls The correct handle to refer to the idr/etc is ib_uverbs_file, revise all the core APIs to use this instead. The user API are left as wrappers that automatically convert a ucontext to a ufile for now. Signed-off-by: Jason Gunthorpe Signed-off-by: Leon Romanovsky --- drivers/infiniband/core/rdma_core.c | 66 +++++++++++++------------- drivers/infiniband/core/rdma_core.h | 21 ++++---- drivers/infiniband/core/uverbs_ioctl.c | 4 +- drivers/infiniband/core/uverbs_main.c | 15 +++--- include/rdma/uverbs_std_types.h | 16 +++---- include/rdma/uverbs_types.h | 8 ++-- 6 files changed, 62 insertions(+), 68 deletions(-) diff --git a/drivers/infiniband/core/rdma_core.c b/drivers/infiniband/core/rdma_core.c index 11c6f271be00..dcaf3813ee78 100644 --- a/drivers/infiniband/core/rdma_core.c +++ b/drivers/infiniband/core/rdma_core.c @@ -139,7 +139,7 @@ int __uobj_perform_destroy(const struct uverbs_obj_type *type, int id, struct ib_uobject *uobj; int ret; - uobj = rdma_lookup_get_uobject(type, ufile->ucontext, id, true); + uobj = rdma_lookup_get_uobject(type, ufile, id, true); if (IS_ERR(uobj)) return PTR_ERR(uobj); @@ -150,7 +150,7 @@ int __uobj_perform_destroy(const struct uverbs_obj_type *type, int id, return success_res; } -static struct ib_uobject *alloc_uobj(struct ib_ucontext *context, +static struct ib_uobject *alloc_uobj(struct ib_uverbs_file *ufile, const struct uverbs_obj_type *type) { struct ib_uobject *uobj = kzalloc(type->obj_size, GFP_KERNEL); @@ -161,8 +161,8 @@ static struct ib_uobject *alloc_uobj(struct ib_ucontext *context, * user_handle should be filled by the handler, * The object is added to the list in the commit stage. */ - uobj->ufile = context->ufile; - uobj->context = context; + uobj->ufile = ufile; + uobj->context = ufile->ucontext; uobj->type = type; /* * Allocated objects start out as write locked to deny any other @@ -210,15 +210,15 @@ static void uverbs_idr_remove_uobj(struct ib_uobject *uobj) } /* Returns the ib_uobject or an error. The caller should check for IS_ERR. */ -static struct ib_uobject *lookup_get_idr_uobject(const struct uverbs_obj_type *type, - struct ib_ucontext *ucontext, - int id, bool exclusive) +static struct ib_uobject * +lookup_get_idr_uobject(const struct uverbs_obj_type *type, + struct ib_uverbs_file *ufile, int id, bool exclusive) { struct ib_uobject *uobj; rcu_read_lock(); /* object won't be released as we're protected in rcu */ - uobj = idr_find(&ucontext->ufile->idr, id); + uobj = idr_find(&ufile->idr, id); if (!uobj) { uobj = ERR_PTR(-ENOENT); goto free; @@ -239,7 +239,7 @@ free: } static struct ib_uobject *lookup_get_fd_uobject(const struct uverbs_obj_type *type, - struct ib_ucontext *ucontext, + struct ib_uverbs_file *ufile, int id, bool exclusive) { struct file *f; @@ -270,13 +270,13 @@ static struct ib_uobject *lookup_get_fd_uobject(const struct uverbs_obj_type *ty } struct ib_uobject *rdma_lookup_get_uobject(const struct uverbs_obj_type *type, - struct ib_ucontext *ucontext, - int id, bool exclusive) + struct ib_uverbs_file *ufile, int id, + bool exclusive) { struct ib_uobject *uobj; int ret; - uobj = type->type_class->lookup_get(type, ucontext, id, exclusive); + uobj = type->type_class->lookup_get(type, ufile, id, exclusive); if (IS_ERR(uobj)) return uobj; @@ -300,12 +300,12 @@ free: } static struct ib_uobject *alloc_begin_idr_uobject(const struct uverbs_obj_type *type, - struct ib_ucontext *ucontext) + struct ib_uverbs_file *ufile) { int ret; struct ib_uobject *uobj; - uobj = alloc_uobj(ucontext, type); + uobj = alloc_uobj(ufile, type); if (IS_ERR(uobj)) return uobj; @@ -313,7 +313,7 @@ static struct ib_uobject *alloc_begin_idr_uobject(const struct uverbs_obj_type * if (ret) goto uobj_put; - ret = ib_rdmacg_try_charge(&uobj->cg_obj, ucontext->device, + ret = ib_rdmacg_try_charge(&uobj->cg_obj, ufile->ucontext->device, RDMACG_RESOURCE_HCA_OBJECT); if (ret) goto idr_remove; @@ -328,7 +328,7 @@ uobj_put: } static struct ib_uobject *alloc_begin_fd_uobject(const struct uverbs_obj_type *type, - struct ib_ucontext *ucontext) + struct ib_uverbs_file *ufile) { const struct uverbs_obj_fd_type *fd_type = container_of(type, struct uverbs_obj_fd_type, type); @@ -341,7 +341,7 @@ static struct ib_uobject *alloc_begin_fd_uobject(const struct uverbs_obj_type *t if (new_fd < 0) return ERR_PTR(new_fd); - uobj = alloc_uobj(ucontext, type); + uobj = alloc_uobj(ufile, type); if (IS_ERR(uobj)) { put_unused_fd(new_fd); return uobj; @@ -360,7 +360,7 @@ static struct ib_uobject *alloc_begin_fd_uobject(const struct uverbs_obj_type *t uobj_file->uobj.id = new_fd; uobj_file->uobj.object = filp; - uobj_file->ufile = ucontext->ufile; + uobj_file->ufile = ufile; INIT_LIST_HEAD(&uobj->list); kref_get(&uobj_file->ufile->ref); @@ -368,9 +368,9 @@ static struct ib_uobject *alloc_begin_fd_uobject(const struct uverbs_obj_type *t } struct ib_uobject *rdma_alloc_begin_uobject(const struct uverbs_obj_type *type, - struct ib_ucontext *ucontext) + struct ib_uverbs_file *ufile) { - return type->type_class->alloc_begin(type, ucontext); + return type->type_class->alloc_begin(type, ufile); } static int __must_check remove_commit_idr_uobject(struct ib_uobject *uobj, @@ -669,10 +669,9 @@ void uverbs_close_fd(struct file *f) kref_put(uverbs_file_ref, ib_uverbs_release_file); } -static int __uverbs_cleanup_ucontext(struct ib_ucontext *ucontext, - enum rdma_remove_reason reason) +static int __uverbs_cleanup_ufile(struct ib_uverbs_file *ufile, + enum rdma_remove_reason reason) { - struct ib_uverbs_file *ufile = ucontext->ufile; struct ib_uobject *obj, *next_obj; int ret = -EINVAL; int err = 0; @@ -716,12 +715,11 @@ static int __uverbs_cleanup_ucontext(struct ib_ucontext *ucontext, return ret; } -void uverbs_cleanup_ucontext(struct ib_ucontext *ucontext, bool device_removed) +void uverbs_cleanup_ufile(struct ib_uverbs_file *ufile, bool device_removed) { enum rdma_remove_reason reason = device_removed ? RDMA_REMOVE_DRIVER_REMOVE : RDMA_REMOVE_CLOSE; - struct ib_uverbs_file *ufile = ucontext->ufile; /* * Waits for all remove_commit and alloc_commit to finish. Logically, We @@ -731,7 +729,7 @@ void uverbs_cleanup_ucontext(struct ib_ucontext *ucontext, bool device_removed) down_write(&ufile->cleanup_rwsem); ufile->ucontext->cleanup_retryable = true; while (!list_empty(&ufile->uobjects)) - if (__uverbs_cleanup_ucontext(ucontext, reason)) { + if (__uverbs_cleanup_ufile(ufile, reason)) { /* * No entry was cleaned-up successfully during this * iteration @@ -741,7 +739,7 @@ void uverbs_cleanup_ucontext(struct ib_ucontext *ucontext, bool device_removed) ufile->ucontext->cleanup_retryable = false; if (!list_empty(&ufile->uobjects)) - __uverbs_cleanup_ucontext(ucontext, reason); + __uverbs_cleanup_ufile(ufile, reason); up_write(&ufile->cleanup_rwsem); } @@ -757,19 +755,19 @@ const struct uverbs_obj_type_class uverbs_fd_class = { }; EXPORT_SYMBOL(uverbs_fd_class); -struct ib_uobject *uverbs_get_uobject_from_context(const struct uverbs_obj_type *type_attrs, - struct ib_ucontext *ucontext, - enum uverbs_obj_access access, - int id) +struct ib_uobject * +uverbs_get_uobject_from_file(const struct uverbs_obj_type *type_attrs, + struct ib_uverbs_file *ufile, + enum uverbs_obj_access access, int id) { switch (access) { case UVERBS_ACCESS_READ: - return rdma_lookup_get_uobject(type_attrs, ucontext, id, false); + return rdma_lookup_get_uobject(type_attrs, ufile, id, false); case UVERBS_ACCESS_DESTROY: case UVERBS_ACCESS_WRITE: - return rdma_lookup_get_uobject(type_attrs, ucontext, id, true); + return rdma_lookup_get_uobject(type_attrs, ufile, id, true); case UVERBS_ACCESS_NEW: - return rdma_alloc_begin_uobject(type_attrs, ucontext); + return rdma_alloc_begin_uobject(type_attrs, ufile); default: WARN_ON(true); return ERR_PTR(-EOPNOTSUPP); diff --git a/drivers/infiniband/core/rdma_core.h b/drivers/infiniband/core/rdma_core.h index f7f157e78f8c..1bba60e960c1 100644 --- a/drivers/infiniband/core/rdma_core.h +++ b/drivers/infiniband/core/rdma_core.h @@ -48,14 +48,8 @@ const struct uverbs_object_spec *uverbs_get_object(struct ib_uverbs_file *ufile, uint16_t object); const struct uverbs_method_spec *uverbs_get_method(const struct uverbs_object_spec *object, uint16_t method); -/* - * These functions initialize the context and cleanups its uobjects. - * The context has a list of objects which is protected by a mutex - * on the context. initialize_ucontext should be called when we create - * a context. - * cleanup_ucontext removes all uobjects from the context and puts them. - */ -void uverbs_cleanup_ucontext(struct ib_ucontext *ucontext, bool device_removed); + +void uverbs_cleanup_ufile(struct ib_uverbs_file *ufile, bool device_removed); /* * uverbs_uobject_get is called in order to increase the reference count on @@ -81,7 +75,7 @@ void uverbs_uobject_put(struct ib_uobject *uobject); void uverbs_close_fd(struct file *f); /* - * Get an ib_uobject that corresponds to the given id from ucontext, assuming + * Get an ib_uobject that corresponds to the given id from ufile, assuming * the object is from the given type. Lock it to the required access when * applicable. * This function could create (access == NEW), destroy (access == DESTROY) @@ -89,10 +83,11 @@ void uverbs_close_fd(struct file *f); * The action will be finalized only when uverbs_finalize_object or * uverbs_finalize_objects are called. */ -struct ib_uobject *uverbs_get_uobject_from_context(const struct uverbs_obj_type *type_attrs, - struct ib_ucontext *ucontext, - enum uverbs_obj_access access, - int id); +struct ib_uobject * +uverbs_get_uobject_from_file(const struct uverbs_obj_type *type_attrs, + struct ib_uverbs_file *ufile, + enum uverbs_obj_access access, int id); + /* * Note that certain finalize stages could return a status: * (a) alloc_commit could return a failure if the object is committed at the diff --git a/drivers/infiniband/core/uverbs_ioctl.c b/drivers/infiniband/core/uverbs_ioctl.c index 5b59c6f0feed..d3bf82cfaa2b 100644 --- a/drivers/infiniband/core/uverbs_ioctl.c +++ b/drivers/infiniband/core/uverbs_ioctl.c @@ -152,9 +152,9 @@ static int uverbs_process_attr(struct ib_uverbs_file *ufile, if (!object) return -EINVAL; - o_attr->uobject = uverbs_get_uobject_from_context( + o_attr->uobject = uverbs_get_uobject_from_file( object->type_attrs, - ufile->ucontext, + ufile, spec->u.obj.access, (int)uattr->data); diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c index 82168b53e2ae..037c8975d9f0 100644 --- a/drivers/infiniband/core/uverbs_main.c +++ b/drivers/infiniband/core/uverbs_main.c @@ -227,12 +227,13 @@ void ib_uverbs_detach_umcast(struct ib_qp *qp, } } -static int ib_uverbs_cleanup_ucontext(struct ib_uverbs_file *file, - struct ib_ucontext *context, - bool device_removed) +static int ib_uverbs_cleanup_ufile(struct ib_uverbs_file *file, + bool device_removed) { + struct ib_ucontext *context = file->ucontext; + context->closing = 1; - uverbs_cleanup_ucontext(context, device_removed); + uverbs_cleanup_ufile(file, device_removed); put_pid(context->tgid); ib_rdmacg_uncharge(&context->cg_obj, context->device, @@ -918,7 +919,7 @@ static int ib_uverbs_close(struct inode *inode, struct file *filp) mutex_lock(&file->cleanup_mutex); if (file->ucontext) { - ib_uverbs_cleanup_ucontext(file, file->ucontext, false); + ib_uverbs_cleanup_ufile(file, false); file->ucontext = NULL; } mutex_unlock(&file->cleanup_mutex); @@ -1176,7 +1177,7 @@ static void ib_uverbs_free_hw_resources(struct ib_uverbs_device *uverbs_dev, mutex_unlock(&file->cleanup_mutex); /* At this point ib_uverbs_close cannot be running - * ib_uverbs_cleanup_ucontext + * ib_uverbs_cleanup_ufile */ if (ucontext) { /* We must release the mutex before going ahead and @@ -1188,7 +1189,7 @@ static void ib_uverbs_free_hw_resources(struct ib_uverbs_device *uverbs_dev, ib_uverbs_event_handler(&file->event_handler, &event); ib_uverbs_disassociate_ucontext(ucontext); mutex_lock(&file->cleanup_mutex); - ib_uverbs_cleanup_ucontext(file, ucontext, true); + ib_uverbs_cleanup_ufile(file, true); mutex_unlock(&file->cleanup_mutex); } diff --git a/include/rdma/uverbs_std_types.h b/include/rdma/uverbs_std_types.h index 27c24453fc12..13b92020edd0 100644 --- a/include/rdma/uverbs_std_types.h +++ b/include/rdma/uverbs_std_types.h @@ -48,28 +48,28 @@ static inline const struct uverbs_object_tree_def *uverbs_default_get_objects(vo static inline struct ib_uobject *__uobj_get(const struct uverbs_obj_type *type, bool write, - struct ib_ucontext *ucontext, + struct ib_uverbs_file *ufile, int id) { - return rdma_lookup_get_uobject(type, ucontext, id, write); + return rdma_lookup_get_uobject(type, ufile, id, write); } #define uobj_get_type(_object) UVERBS_OBJECT(_object).type_attrs -#define uobj_get_read(_type, _id, _ucontext) \ - __uobj_get(uobj_get_type(_type), false, _ucontext, _id) +#define uobj_get_read(_type, _id, _ucontext) \ + __uobj_get(uobj_get_type(_type), false, (_ucontext)->ufile, _id) #define uobj_get_obj_read(_object, _type, _id, _ucontext) \ ({ \ struct ib_uobject *__uobj = \ __uobj_get(uobj_get_type(_type), \ - false, _ucontext, _id); \ + false, (_ucontext)->ufile, _id); \ \ (struct ib_##_object *)(IS_ERR(__uobj) ? NULL : __uobj->object);\ }) -#define uobj_get_write(_type, _id, _ucontext) \ - __uobj_get(uobj_get_type(_type), true, _ucontext, _id) +#define uobj_get_write(_type, _id, _ucontext) \ + __uobj_get(uobj_get_type(_type), true, (_ucontext)->ufile, _id) int __uobj_perform_destroy(const struct uverbs_obj_type *type, int id, struct ib_uverbs_file *ufile, int success_res); @@ -107,7 +107,7 @@ static inline void uobj_alloc_abort(struct ib_uobject *uobj) static inline struct ib_uobject *__uobj_alloc(const struct uverbs_obj_type *type, struct ib_ucontext *ucontext) { - return rdma_alloc_begin_uobject(type, ucontext); + return rdma_alloc_begin_uobject(type, ucontext->ufile); } #define uobj_alloc(_type, ucontext) \ diff --git a/include/rdma/uverbs_types.h b/include/rdma/uverbs_types.h index 175495d1b0b8..5290d8d34e9a 100644 --- a/include/rdma/uverbs_types.h +++ b/include/rdma/uverbs_types.h @@ -72,12 +72,12 @@ struct uverbs_obj_type_class { * reset flow). */ struct ib_uobject *(*alloc_begin)(const struct uverbs_obj_type *type, - struct ib_ucontext *ucontext); + struct ib_uverbs_file *ufile); void (*alloc_commit)(struct ib_uobject *uobj); void (*alloc_abort)(struct ib_uobject *uobj); struct ib_uobject *(*lookup_get)(const struct uverbs_obj_type *type, - struct ib_ucontext *ucontext, int id, + struct ib_uverbs_file *ufile, int id, bool exclusive); void (*lookup_put)(struct ib_uobject *uobj, bool exclusive); /* @@ -120,11 +120,11 @@ struct uverbs_obj_idr_type { }; struct ib_uobject *rdma_lookup_get_uobject(const struct uverbs_obj_type *type, - struct ib_ucontext *ucontext, + struct ib_uverbs_file *ufile, int id, bool exclusive); void rdma_lookup_put_uobject(struct ib_uobject *uobj, bool exclusive); struct ib_uobject *rdma_alloc_begin_uobject(const struct uverbs_obj_type *type, - struct ib_ucontext *ucontext); + struct ib_uverbs_file *ufile); void rdma_alloc_abort_uobject(struct ib_uobject *uobj); int __must_check rdma_remove_commit_uobject(struct ib_uobject *uobj); int rdma_alloc_commit_uobject(struct ib_uobject *uobj);