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

Commit 87fc2a62 authored by Jason Gunthorpe's avatar Jason Gunthorpe
Browse files

RDMA/uverbs: Store the specs_root in the struct ib_uverbs_device



The specs are required to operate the uverbs file, so they belong inside
the ib_uverbs_device, not inside the ib_device. The spec passed in the
ib_device is just a communication from the driver and should not be used
during runtime.

This also changes the lifetime of the spec memory to match the
ib_uverbs_device, however at this time the spec_root can still contain
driver pointers after disassociation, so it cannot be used if ib_dev is
NULL. This is preparation for another series.

Signed-off-by: default avatarJason Gunthorpe <jgg@mellanox.com>
Reviewed-by: default avatarMichael J. Ruhl <michael.j.ruhl@intel.com>
Signed-off-by: default avatarLeon Romanovsky <leonro@mellanox.com>
parent 8193abb6
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -52,10 +52,10 @@ int uverbs_ns_idx(u16 *id, unsigned int ns_count)
	return ret;
}

const struct uverbs_object_spec *uverbs_get_object(const struct ib_device *ibdev,
const struct uverbs_object_spec *uverbs_get_object(struct ib_uverbs_file *ufile,
						   uint16_t object)
{
	const struct uverbs_root_spec *object_hash = ibdev->specs_root;
	const struct uverbs_root_spec *object_hash = ufile->device->specs_root;
	const struct uverbs_object_spec_hash *objects;
	int ret = uverbs_ns_idx(&object, object_hash->num_buckets);

+1 −1
Original line number Diff line number Diff line
@@ -44,7 +44,7 @@
#include <linux/mutex.h>

int uverbs_ns_idx(u16 *id, unsigned int ns_count);
const struct uverbs_object_spec *uverbs_get_object(const struct ib_device *ibdev,
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);
+12 −14
Original line number Diff line number Diff line
@@ -46,8 +46,7 @@ static bool uverbs_is_attr_cleared(const struct ib_uverbs_attr *uattr,
			   0, uattr->len - len);
}

static int uverbs_process_attr(struct ib_device *ibdev,
			       struct ib_ucontext *ucontext,
static int uverbs_process_attr(struct ib_uverbs_file *ufile,
			       const struct ib_uverbs_attr *uattr,
			       u16 attr_id,
			       const struct uverbs_attr_spec_hash *attr_spec_bucket,
@@ -145,17 +144,18 @@ static int uverbs_process_attr(struct ib_device *ibdev,
		if (uattr->attr_data.reserved)
			return -EINVAL;

		if (uattr->len != 0 || !ucontext || uattr->data > INT_MAX)
		if (uattr->len != 0 || !ufile->ucontext ||
		    uattr->data > INT_MAX)
			return -EINVAL;

		o_attr = &e->obj_attr;
		object = uverbs_get_object(ibdev, spec->obj.obj_type);
		object = uverbs_get_object(ufile, spec->obj.obj_type);
		if (!object)
			return -EINVAL;

		o_attr->uobject = uverbs_get_uobject_from_context(
					object->type_attrs,
					ucontext,
					ufile->ucontext,
					spec->obj.access,
					(int)uattr->data);

@@ -230,8 +230,7 @@ static int uverbs_finalize_attrs(struct uverbs_attr_bundle *attrs_bundle,
	return ret;
}

static int uverbs_uattrs_process(struct ib_device *ibdev,
				 struct ib_ucontext *ucontext,
static int uverbs_uattrs_process(struct ib_uverbs_file *ufile,
				 const struct ib_uverbs_attr *uattrs,
				 size_t num_uattrs,
				 const struct uverbs_method_spec *method,
@@ -267,9 +266,9 @@ static int uverbs_uattrs_process(struct ib_device *ibdev,
			num_given_buckets = ret + 1;

		attr_spec_bucket = method->attr_buckets[ret];
		ret = uverbs_process_attr(ibdev, ucontext, uattr, attr_id,
					  attr_spec_bucket, &attr_bundle->hash[ret],
					  uattr_ptr++);
		ret = uverbs_process_attr(ufile, uattr, attr_id,
					  attr_spec_bucket,
					  &attr_bundle->hash[ret], uattr_ptr++);
		if (ret) {
			uverbs_finalize_attrs(attr_bundle,
					      method->attr_buckets,
@@ -324,9 +323,8 @@ static int uverbs_handle_method(struct ib_uverbs_attr __user *uattr_ptr,
	int finalize_ret;
	int num_given_buckets;

	num_given_buckets = uverbs_uattrs_process(ibdev, ufile->ucontext, uattrs,
						  num_uattrs, method_spec,
						  attr_bundle, uattr_ptr);
	num_given_buckets = uverbs_uattrs_process(
		ufile, uattrs, num_uattrs, method_spec, attr_bundle, uattr_ptr);
	if (num_given_buckets <= 0)
		return -EINVAL;

@@ -367,7 +365,7 @@ static long ib_uverbs_cmd_verbs(struct ib_device *ib_dev,
	if (hdr->driver_id != ib_dev->driver_id)
		return -EINVAL;

	object_spec = uverbs_get_object(ib_dev, hdr->object_id);
	object_spec = uverbs_get_object(file, hdr->object_id);
	if (!object_spec)
		return -EPROTONOSUPPORT;

+9 −7
Original line number Diff line number Diff line
@@ -161,6 +161,7 @@ static void ib_uverbs_release_dev(struct kobject *kobj)
		container_of(kobj, struct ib_uverbs_device, kobj);

	cleanup_srcu_struct(&dev->disassociate_srcu);
	uverbs_free_spec_tree(dev->specs_root);
	kfree(dev);
}

@@ -1067,7 +1068,7 @@ static void ib_uverbs_add_one(struct ib_device *device)
	if (device_create_file(uverbs_dev->dev, &dev_attr_abi_version))
		goto err_class;

	if (!device->specs_root) {
	if (!device->driver_specs_root) {
		const struct uverbs_object_tree_def *default_root[] = {
			uverbs_default_get_objects()};

@@ -1075,8 +1076,13 @@ static void ib_uverbs_add_one(struct ib_device *device)
								default_root);
		if (IS_ERR(uverbs_dev->specs_root))
			goto err_class;

		device->specs_root = uverbs_dev->specs_root;
	} else {
		uverbs_dev->specs_root = device->driver_specs_root;
		/*
		 * Take responsibility to free the specs allocated by the
		 * driver.
		 */
		device->driver_specs_root = NULL;
	}

	ib_set_client_data(device, &uverbs_client, uverbs_dev);
@@ -1241,10 +1247,6 @@ static void ib_uverbs_remove_one(struct ib_device *device, void *client_data)
		ib_uverbs_comp_dev(uverbs_dev);
	if (wait_clients)
		wait_for_completion(&uverbs_dev->comp);
	if (uverbs_dev->specs_root) {
		uverbs_free_spec_tree(uverbs_dev->specs_root);
		device->specs_root = NULL;
	}

	kobject_put(&uverbs_dev->kobj);
}
+3 −3
Original line number Diff line number Diff line
@@ -5350,15 +5350,15 @@ static int populate_specs_root(struct mlx5_ib_dev *dev)
	    !WARN_ON(num_trees >= ARRAY_SIZE(default_root)))
		default_root[num_trees++] = mlx5_ib_get_devx_tree();

	dev->ib_dev.specs_root =
	dev->ib_dev.driver_specs_root =
		uverbs_alloc_spec_tree(num_trees, default_root);

	return PTR_ERR_OR_ZERO(dev->ib_dev.specs_root);
	return PTR_ERR_OR_ZERO(dev->ib_dev.driver_specs_root);
}

static void depopulate_specs_root(struct mlx5_ib_dev *dev)
{
	uverbs_free_spec_tree(dev->ib_dev.specs_root);
	uverbs_free_spec_tree(dev->ib_dev.driver_specs_root);
}

static int mlx5_ib_read_counters(struct ib_counters *counters,
Loading