Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6ef1c828 authored by Jason Gunthorpe's avatar Jason Gunthorpe
Browse files

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: default avatarJason Gunthorpe <jgg@mellanox.com>
Signed-off-by: default avatarLeon Romanovsky <leonro@mellanox.com>
parent 6a5e9c88
Loading
Loading
Loading
Loading
+32 −34
Original line number Diff line number Diff line
@@ -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 @@ static struct ib_uobject *lookup_get_idr_uobject(const struct uverbs_obj_type *t
}

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 @@ struct ib_uobject *rdma_lookup_get_uobject(const struct uverbs_obj_type *type,
}

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 @@ static struct ib_uobject *alloc_begin_idr_uobject(const struct uverbs_obj_type *
}

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,
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);
+8 −13
Original line number Diff line number Diff line
@@ -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
+2 −2
Original line number Diff line number Diff line
@@ -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);

+8 −7
Original line number Diff line number Diff line
@@ -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,
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);
		}

+8 −8
Original line number Diff line number Diff line
@@ -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)
	__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)
	__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)	\
Loading