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

Commit a6a3797d authored by Shamir Rabinovitch's avatar Shamir Rabinovitch Committed by Jason Gunthorpe
Browse files

IB: Pass uverbs_attr_bundle down uobject destroy path



Pass uverbs_attr_bundle down the uobject destroy path. The next patch will
use this to eliminate the dependecy of the drivers in ib_x->uobject
pointers.

Signed-off-by: default avatarShamir Rabinovitch <shamir.rabinovitch@oracle.com>
Signed-off-by: default avatarJason Gunthorpe <jgg@mellanox.com>
parent 70f06b26
Loading
Loading
Loading
Loading
+30 −18
Original line number Diff line number Diff line
@@ -125,7 +125,8 @@ static void assert_uverbs_usecnt(struct ib_uobject *uobj,
 * and consumes the kref on the uobj.
 */
static int uverbs_destroy_uobject(struct ib_uobject *uobj,
				  enum rdma_remove_reason reason)
				  enum rdma_remove_reason reason,
				  struct uverbs_attr_bundle *attrs)
{
	struct ib_uverbs_file *ufile = uobj->ufile;
	unsigned long flags;
@@ -135,7 +136,8 @@ static int uverbs_destroy_uobject(struct ib_uobject *uobj,
	assert_uverbs_usecnt(uobj, UVERBS_LOOKUP_WRITE);

	if (uobj->object) {
		ret = uobj->uapi_object->type_class->destroy_hw(uobj, reason);
		ret = uobj->uapi_object->type_class->destroy_hw(uobj, reason,
								attrs);
		if (ret) {
			if (ib_is_destroy_retryable(ret, reason, uobj))
				return ret;
@@ -196,7 +198,7 @@ static int uverbs_destroy_uobject(struct ib_uobject *uobj,
 * version requires the caller to have already obtained an
 * LOOKUP_DESTROY uobject kref.
 */
int uobj_destroy(struct ib_uobject *uobj)
int uobj_destroy(struct ib_uobject *uobj, struct uverbs_attr_bundle *attrs)
{
	struct ib_uverbs_file *ufile = uobj->ufile;
	int ret;
@@ -207,7 +209,7 @@ int uobj_destroy(struct ib_uobject *uobj)
	if (ret)
		goto out_unlock;

	ret = uverbs_destroy_uobject(uobj, RDMA_REMOVE_DESTROY);
	ret = uverbs_destroy_uobject(uobj, RDMA_REMOVE_DESTROY, attrs);
	if (ret) {
		atomic_set(&uobj->usecnt, 0);
		goto out_unlock;
@@ -234,7 +236,7 @@ struct ib_uobject *__uobj_get_destroy(const struct uverbs_api_object *obj,
	if (IS_ERR(uobj))
		return uobj;

	ret = uobj_destroy(uobj);
	ret = uobj_destroy(uobj, attrs);
	if (ret) {
		rdma_lookup_put_uobject(uobj, UVERBS_LOOKUP_DESTROY);
		return ERR_PTR(ret);
@@ -533,12 +535,13 @@ static void alloc_abort_idr_uobject(struct ib_uobject *uobj)
}

static int __must_check destroy_hw_idr_uobject(struct ib_uobject *uobj,
					       enum rdma_remove_reason why)
					       enum rdma_remove_reason why,
					       struct uverbs_attr_bundle *attrs)
{
	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);
	int ret = idr_type->destroy_object(uobj, why, attrs);

	/*
	 * We can only fail gracefully if the user requested to destroy the
@@ -572,7 +575,8 @@ static void alloc_abort_fd_uobject(struct ib_uobject *uobj)
}

static int __must_check destroy_hw_fd_uobject(struct ib_uobject *uobj,
					      enum rdma_remove_reason why)
					      enum rdma_remove_reason why,
					      struct uverbs_attr_bundle *attrs)
{
	const struct uverbs_obj_fd_type *fd_type = container_of(
		uobj->uapi_object->type_attrs, struct uverbs_obj_fd_type, type);
@@ -648,7 +652,8 @@ static int alloc_commit_fd_uobject(struct ib_uobject *uobj)
 * caller can no longer assume uobj is valid. If this function fails it
 * destroys the uboject, including the attached HW object.
 */
int __must_check rdma_alloc_commit_uobject(struct ib_uobject *uobj)
int __must_check rdma_alloc_commit_uobject(struct ib_uobject *uobj,
					   struct uverbs_attr_bundle *attrs)
{
	struct ib_uverbs_file *ufile = uobj->ufile;
	int ret;
@@ -656,7 +661,7 @@ int __must_check rdma_alloc_commit_uobject(struct ib_uobject *uobj)
	/* alloc_commit consumes the uobj kref */
	ret = uobj->uapi_object->type_class->alloc_commit(uobj);
	if (ret) {
		uverbs_destroy_uobject(uobj, RDMA_REMOVE_ABORT);
		uverbs_destroy_uobject(uobj, RDMA_REMOVE_ABORT, attrs);
		up_read(&ufile->hw_destroy_rwsem);
		return ret;
	}
@@ -680,12 +685,13 @@ int __must_check rdma_alloc_commit_uobject(struct ib_uobject *uobj)
 * This consumes the kref for uobj. It is up to the caller to unwind the HW
 * object and anything else connected to uobj before calling this.
 */
void rdma_alloc_abort_uobject(struct ib_uobject *uobj)
void rdma_alloc_abort_uobject(struct ib_uobject *uobj,
			      struct uverbs_attr_bundle *attrs)
{
	struct ib_uverbs_file *ufile = uobj->ufile;

	uobj->object = NULL;
	uverbs_destroy_uobject(uobj, RDMA_REMOVE_ABORT);
	uverbs_destroy_uobject(uobj, RDMA_REMOVE_ABORT, attrs);

	/* Matches the down_read in rdma_alloc_begin_uobject */
	up_read(&ufile->hw_destroy_rwsem);
@@ -787,6 +793,10 @@ void uverbs_close_fd(struct file *f)
{
	struct ib_uobject *uobj = f->private_data;
	struct ib_uverbs_file *ufile = uobj->ufile;
	struct uverbs_attr_bundle attrs = {
		.context = uobj->context,
		.ufile = ufile,
	};

	if (down_read_trylock(&ufile->hw_destroy_rwsem)) {
		/*
@@ -796,7 +806,7 @@ void uverbs_close_fd(struct file *f)
		 * write lock here, or we have a kernel bug.
		 */
		WARN_ON(uverbs_try_lock_object(uobj, UVERBS_LOOKUP_WRITE));
		uverbs_destroy_uobject(uobj, RDMA_REMOVE_CLOSE);
		uverbs_destroy_uobject(uobj, RDMA_REMOVE_CLOSE, &attrs);
		up_read(&ufile->hw_destroy_rwsem);
	}

@@ -845,6 +855,7 @@ static int __uverbs_cleanup_ufile(struct ib_uverbs_file *ufile,
{
	struct ib_uobject *obj, *next_obj;
	int ret = -EINVAL;
	struct uverbs_attr_bundle attrs = { .ufile = ufile };

	/*
	 * This shouldn't run while executing other commands on this
@@ -856,12 +867,13 @@ static int __uverbs_cleanup_ufile(struct ib_uverbs_file *ufile,
	 * other threads (which might still use the FDs) chance to run.
	 */
	list_for_each_entry_safe(obj, next_obj, &ufile->uobjects, list) {
		attrs.context = obj->context;
		/*
		 * if we hit this WARN_ON, that means we are
		 * racing with a lookup_get.
		 */
		WARN_ON(uverbs_try_lock_object(obj, UVERBS_LOOKUP_WRITE));
		if (!uverbs_destroy_uobject(obj, reason))
		if (!uverbs_destroy_uobject(obj, reason, &attrs))
			ret = 0;
		else
			atomic_set(&obj->usecnt, 0);
@@ -966,8 +978,8 @@ uverbs_get_uobject_from_file(u16 object_id, enum uverbs_obj_access access,
}

int uverbs_finalize_object(struct ib_uobject *uobj,
			   enum uverbs_obj_access access,
			   bool commit)
			   enum uverbs_obj_access access, bool commit,
			   struct uverbs_attr_bundle *attrs)
{
	int ret = 0;

@@ -990,9 +1002,9 @@ int uverbs_finalize_object(struct ib_uobject *uobj,
		break;
	case UVERBS_ACCESS_NEW:
		if (commit)
			ret = rdma_alloc_commit_uobject(uobj);
			ret = rdma_alloc_commit_uobject(uobj, attrs);
		else
			rdma_alloc_abort_uobject(uobj);
			rdma_alloc_abort_uobject(uobj, attrs);
		break;
	default:
		WARN_ON(true);
+3 −3
Original line number Diff line number Diff line
@@ -48,7 +48,7 @@ struct ib_uverbs_device;
void uverbs_destroy_ufile_hw(struct ib_uverbs_file *ufile,
			     enum rdma_remove_reason reason);

int uobj_destroy(struct ib_uobject *uobj);
int uobj_destroy(struct ib_uobject *uobj, struct uverbs_attr_bundle *attrs);

/*
 * uverbs_uobject_get is called in order to increase the reference count on
@@ -102,8 +102,8 @@ uverbs_get_uobject_from_file(u16 object_id, enum uverbs_obj_access access,
 * object.
 */
int uverbs_finalize_object(struct ib_uobject *uobj,
			   enum uverbs_obj_access access,
			   bool commit);
			   enum uverbs_obj_access access, bool commit,
			   struct uverbs_attr_bundle *attrs);

int uverbs_output_written(const struct uverbs_attr_bundle *bundle, size_t idx);

+26 −26
Original line number Diff line number Diff line
@@ -436,7 +436,7 @@ static int ib_uverbs_alloc_pd(struct uverbs_attr_bundle *attrs)
	if (ret)
		goto err_copy;

	return uobj_alloc_commit(uobj);
	return uobj_alloc_commit(uobj, attrs);

err_copy:
	ib_dealloc_pd(pd);
@@ -444,7 +444,7 @@ static int ib_uverbs_alloc_pd(struct uverbs_attr_bundle *attrs)
err_alloc:
	kfree(pd);
err:
	uobj_alloc_abort(uobj);
	uobj_alloc_abort(uobj, attrs);
	return ret;
}

@@ -633,7 +633,7 @@ static int ib_uverbs_open_xrcd(struct uverbs_attr_bundle *attrs)

	mutex_unlock(&ibudev->xrcd_tree_mutex);

	return uobj_alloc_commit(&obj->uobject);
	return uobj_alloc_commit(&obj->uobject, attrs);

err_copy:
	if (inode) {
@@ -646,7 +646,7 @@ static int ib_uverbs_open_xrcd(struct uverbs_attr_bundle *attrs)
	ib_dealloc_xrcd(xrcd);

err:
	uobj_alloc_abort(&obj->uobject);
	uobj_alloc_abort(&obj->uobject, attrs);

err_tree_mutex_unlock:
	if (f.file)
@@ -763,7 +763,7 @@ static int ib_uverbs_reg_mr(struct uverbs_attr_bundle *attrs)

	uobj_put_obj_read(pd);

	return uobj_alloc_commit(uobj);
	return uobj_alloc_commit(uobj, attrs);

err_copy:
	ib_dereg_mr(mr);
@@ -772,7 +772,7 @@ static int ib_uverbs_reg_mr(struct uverbs_attr_bundle *attrs)
	uobj_put_obj_read(pd);

err_free:
	uobj_alloc_abort(uobj);
	uobj_alloc_abort(uobj, attrs);
	return ret;
}

@@ -917,14 +917,14 @@ static int ib_uverbs_alloc_mw(struct uverbs_attr_bundle *attrs)
		goto err_copy;

	uobj_put_obj_read(pd);
	return uobj_alloc_commit(uobj);
	return uobj_alloc_commit(uobj, attrs);

err_copy:
	uverbs_dealloc_mw(mw);
err_put:
	uobj_put_obj_read(pd);
err_free:
	uobj_alloc_abort(uobj);
	uobj_alloc_abort(uobj, attrs);
	return ret;
}

@@ -965,11 +965,11 @@ static int ib_uverbs_create_comp_channel(struct uverbs_attr_bundle *attrs)

	ret = uverbs_response(attrs, &resp, sizeof(resp));
	if (ret) {
		uobj_alloc_abort(uobj);
		uobj_alloc_abort(uobj, attrs);
		return ret;
	}

	return uobj_alloc_commit(uobj);
	return uobj_alloc_commit(uobj, attrs);
}

static struct ib_ucq_object *create_cq(struct uverbs_attr_bundle *attrs,
@@ -1036,7 +1036,7 @@ static struct ib_ucq_object *create_cq(struct uverbs_attr_bundle *attrs,
	if (ret)
		goto err_cb;

	ret = uobj_alloc_commit(&obj->uobject);
	ret = uobj_alloc_commit(&obj->uobject, attrs);
	if (ret)
		return ERR_PTR(ret);
	return obj;
@@ -1049,7 +1049,7 @@ static struct ib_ucq_object *create_cq(struct uverbs_attr_bundle *attrs,
		ib_uverbs_release_ucq(attrs->ufile, ev_file, obj);

err:
	uobj_alloc_abort(&obj->uobject);
	uobj_alloc_abort(&obj->uobject, attrs);

	return ERR_PTR(ret);
}
@@ -1477,7 +1477,7 @@ static int create_qp(struct uverbs_attr_bundle *attrs,
	if (ind_tbl)
		uobj_put_obj_read(ind_tbl);

	return uobj_alloc_commit(&obj->uevent.uobject);
	return uobj_alloc_commit(&obj->uevent.uobject, attrs);
err_cb:
	ib_destroy_qp(qp);

@@ -1495,7 +1495,7 @@ static int create_qp(struct uverbs_attr_bundle *attrs,
	if (ind_tbl)
		uobj_put_obj_read(ind_tbl);

	uobj_alloc_abort(&obj->uevent.uobject);
	uobj_alloc_abort(&obj->uevent.uobject, attrs);
	return ret;
}

@@ -1609,14 +1609,14 @@ static int ib_uverbs_open_qp(struct uverbs_attr_bundle *attrs)
	qp->uobject = &obj->uevent.uobject;
	uobj_put_read(xrcd_uobj);

	return uobj_alloc_commit(&obj->uevent.uobject);
	return uobj_alloc_commit(&obj->uevent.uobject, attrs);

err_destroy:
	ib_destroy_qp(qp);
err_xrcd:
	uobj_put_read(xrcd_uobj);
err_put:
	uobj_alloc_abort(&obj->uevent.uobject);
	uobj_alloc_abort(&obj->uevent.uobject, attrs);
	return ret;
}

@@ -2451,7 +2451,7 @@ static int ib_uverbs_create_ah(struct uverbs_attr_bundle *attrs)
		goto err_copy;

	uobj_put_obj_read(pd);
	return uobj_alloc_commit(uobj);
	return uobj_alloc_commit(uobj, attrs);

err_copy:
	rdma_destroy_ah(ah, RDMA_DESTROY_AH_SLEEPABLE);
@@ -2460,7 +2460,7 @@ static int ib_uverbs_create_ah(struct uverbs_attr_bundle *attrs)
	uobj_put_obj_read(pd);

err:
	uobj_alloc_abort(uobj);
	uobj_alloc_abort(uobj, attrs);
	return ret;
}

@@ -2962,7 +2962,7 @@ static int ib_uverbs_ex_create_wq(struct uverbs_attr_bundle *attrs)

	uobj_put_obj_read(pd);
	uobj_put_obj_read(cq);
	return uobj_alloc_commit(&obj->uevent.uobject);
	return uobj_alloc_commit(&obj->uevent.uobject, attrs);

err_copy:
	ib_destroy_wq(wq);
@@ -2971,7 +2971,7 @@ static int ib_uverbs_ex_create_wq(struct uverbs_attr_bundle *attrs)
err_put_pd:
	uobj_put_obj_read(pd);
err_uobj:
	uobj_alloc_abort(&obj->uevent.uobject);
	uobj_alloc_abort(&obj->uevent.uobject, attrs);

	return err;
}
@@ -3136,12 +3136,12 @@ static int ib_uverbs_ex_create_rwq_ind_table(struct uverbs_attr_bundle *attrs)
	for (j = 0; j < num_read_wqs; j++)
		uobj_put_obj_read(wqs[j]);

	return uobj_alloc_commit(uobj);
	return uobj_alloc_commit(uobj, attrs);

err_copy:
	ib_destroy_rwq_ind_table(rwq_ind_tbl);
err_uobj:
	uobj_alloc_abort(uobj);
	uobj_alloc_abort(uobj, attrs);
put_wqs:
	for (j = 0; j < num_read_wqs; j++)
		uobj_put_obj_read(wqs[j]);
@@ -3314,7 +3314,7 @@ static int ib_uverbs_ex_create_flow(struct uverbs_attr_bundle *attrs)
	kfree(flow_attr);
	if (cmd.flow_attr.num_of_specs)
		kfree(kern_flow_attr);
	return uobj_alloc_commit(uobj);
	return uobj_alloc_commit(uobj, attrs);
err_copy:
	if (!qp->device->ops.destroy_flow(flow_id))
		atomic_dec(&qp->usecnt);
@@ -3325,7 +3325,7 @@ static int ib_uverbs_ex_create_flow(struct uverbs_attr_bundle *attrs)
err_put:
	uobj_put_obj_read(qp);
err_uobj:
	uobj_alloc_abort(uobj);
	uobj_alloc_abort(uobj, attrs);
err_free_attr:
	if (cmd.flow_attr.num_of_specs)
		kfree(kern_flow_attr);
@@ -3458,7 +3458,7 @@ static int __uverbs_create_xsrq(struct uverbs_attr_bundle *attrs,
		uobj_put_obj_read(attr.ext.cq);

	uobj_put_obj_read(pd);
	return uobj_alloc_commit(&obj->uevent.uobject);
	return uobj_alloc_commit(&obj->uevent.uobject, attrs);

err_copy:
	ib_destroy_srq(srq);
@@ -3477,7 +3477,7 @@ static int __uverbs_create_xsrq(struct uverbs_attr_bundle *attrs,
	}

err:
	uobj_alloc_abort(&obj->uevent.uobject);
	uobj_alloc_abort(&obj->uevent.uobject, attrs);
	return ret;
}

+9 −6
Original line number Diff line number Diff line
@@ -222,7 +222,7 @@ static int uverbs_process_idrs_array(struct bundle_priv *pbundle,

static int uverbs_free_idrs_array(const struct uverbs_api_attr *attr_uapi,
				  struct uverbs_objs_arr_attr *attr,
				  bool commit)
				  bool commit, struct uverbs_attr_bundle *attrs)
{
	const struct uverbs_attr_spec *spec = &attr_uapi->spec;
	int current_ret;
@@ -230,8 +230,9 @@ static int uverbs_free_idrs_array(const struct uverbs_api_attr *attr_uapi,
	size_t i;

	for (i = 0; i != attr->len; i++) {
		current_ret = uverbs_finalize_object(
			attr->uobjects[i], spec->u2.objs_arr.access, commit);
		current_ret = uverbs_finalize_object(attr->uobjects[i],
						     spec->u2.objs_arr.access,
						     commit, attrs);
		if (!ret)
			ret = current_ret;
	}
@@ -457,7 +458,7 @@ static int ib_uverbs_run_method(struct bundle_priv *pbundle,
		struct uverbs_obj_attr *destroy_attr =
			&pbundle->bundle.attrs[destroy_bkey].obj_attr;

		ret = uobj_destroy(destroy_attr->uobject);
		ret = uobj_destroy(destroy_attr->uobject, &pbundle->bundle);
		if (ret)
			return ret;
		__clear_bit(destroy_bkey, pbundle->uobj_finalize);
@@ -508,7 +509,8 @@ static int bundle_destroy(struct bundle_priv *pbundle, bool commit)

		current_ret = uverbs_finalize_object(
			attr->obj_attr.uobject,
			attr->obj_attr.attr_elm->spec.u.obj.access, commit);
			attr->obj_attr.attr_elm->spec.u.obj.access, commit,
			&pbundle->bundle);
		if (!ret)
			ret = current_ret;
	}
@@ -531,7 +533,8 @@ static int bundle_destroy(struct bundle_priv *pbundle, bool commit)

		if (attr_uapi->spec.type == UVERBS_ATTR_TYPE_IDRS_ARRAY) {
			current_ret = uverbs_free_idrs_array(
				attr_uapi, &attr->objs_arr_attr, commit);
				attr_uapi, &attr->objs_arr_attr, commit,
				&pbundle->bundle);
			if (!ret)
				ret = current_ret;
		}
+18 −9
Original line number Diff line number Diff line
@@ -40,14 +40,16 @@
#include "uverbs.h"

static int uverbs_free_ah(struct ib_uobject *uobject,
			  enum rdma_remove_reason why)
			  enum rdma_remove_reason why,
			  struct uverbs_attr_bundle *attrs)
{
	return rdma_destroy_ah((struct ib_ah *)uobject->object,
			       RDMA_DESTROY_AH_SLEEPABLE);
}

static int uverbs_free_flow(struct ib_uobject *uobject,
			    enum rdma_remove_reason why)
			    enum rdma_remove_reason why,
			    struct uverbs_attr_bundle *attrs)
{
	struct ib_flow *flow = (struct ib_flow *)uobject->object;
	struct ib_uflow_object *uflow =
@@ -66,13 +68,15 @@ static int uverbs_free_flow(struct ib_uobject *uobject,
}

static int uverbs_free_mw(struct ib_uobject *uobject,
			  enum rdma_remove_reason why)
			  enum rdma_remove_reason why,
			  struct uverbs_attr_bundle *attrs)
{
	return uverbs_dealloc_mw((struct ib_mw *)uobject->object);
}

static int uverbs_free_qp(struct ib_uobject *uobject,
			  enum rdma_remove_reason why)
			  enum rdma_remove_reason why,
			  struct uverbs_attr_bundle *attrs)
{
	struct ib_qp *qp = uobject->object;
	struct ib_uqp_object *uqp =
@@ -105,7 +109,8 @@ static int uverbs_free_qp(struct ib_uobject *uobject,
}

static int uverbs_free_rwq_ind_tbl(struct ib_uobject *uobject,
				   enum rdma_remove_reason why)
				   enum rdma_remove_reason why,
				   struct uverbs_attr_bundle *attrs)
{
	struct ib_rwq_ind_table *rwq_ind_tbl = uobject->object;
	struct ib_wq **ind_tbl = rwq_ind_tbl->ind_tbl;
@@ -120,7 +125,8 @@ static int uverbs_free_rwq_ind_tbl(struct ib_uobject *uobject,
}

static int uverbs_free_wq(struct ib_uobject *uobject,
			  enum rdma_remove_reason why)
			  enum rdma_remove_reason why,
			  struct uverbs_attr_bundle *attrs)
{
	struct ib_wq *wq = uobject->object;
	struct ib_uwq_object *uwq =
@@ -136,7 +142,8 @@ static int uverbs_free_wq(struct ib_uobject *uobject,
}

static int uverbs_free_srq(struct ib_uobject *uobject,
			   enum rdma_remove_reason why)
			   enum rdma_remove_reason why,
			   struct uverbs_attr_bundle *attrs)
{
	struct ib_srq *srq = uobject->object;
	struct ib_uevent_object *uevent =
@@ -160,7 +167,8 @@ static int uverbs_free_srq(struct ib_uobject *uobject,
}

static int uverbs_free_xrcd(struct ib_uobject *uobject,
			    enum rdma_remove_reason why)
			    enum rdma_remove_reason why,
			    struct uverbs_attr_bundle *attrs)
{
	struct ib_xrcd *xrcd = uobject->object;
	struct ib_uxrcd_object *uxrcd =
@@ -179,7 +187,8 @@ static int uverbs_free_xrcd(struct ib_uobject *uobject,
}

static int uverbs_free_pd(struct ib_uobject *uobject,
			  enum rdma_remove_reason why)
			  enum rdma_remove_reason why,
			  struct uverbs_attr_bundle *attrs)
{
	struct ib_pd *pd = uobject->object;
	int ret;
Loading