Commit 51d0a2b4 authored by Jason Gunthorpe's avatar Jason Gunthorpe

IB/uverbs: Remove struct uverbs_root_spec and all supporting code

Everything now uses the uverbs_uapi data structure.
Signed-off-by: default avatarJason Gunthorpe <jgg@mellanox.com>
parent 3a863577
......@@ -35,7 +35,7 @@ ib_ucm-y := ucm.o
ib_uverbs-y := uverbs_main.o uverbs_cmd.o uverbs_marshall.o \
rdma_core.o uverbs_std_types.o uverbs_ioctl.o \
uverbs_ioctl_merge.o uverbs_std_types_cq.o \
uverbs_std_types_cq.o \
uverbs_std_types_flow_action.o uverbs_std_types_dm.o \
uverbs_std_types_mr.o uverbs_std_types_counters.o \
uverbs_uapi.o
......@@ -42,51 +42,6 @@
#include "core_priv.h"
#include "rdma_core.h"
int uverbs_ns_idx(u16 *id, unsigned int ns_count)
{
int ret = (*id & UVERBS_ID_NS_MASK) >> UVERBS_ID_NS_SHIFT;
if (ret >= ns_count)
return -EINVAL;
*id &= ~UVERBS_ID_NS_MASK;
return ret;
}
const struct uverbs_object_spec *uverbs_get_object(struct ib_uverbs_file *ufile,
uint16_t object)
{
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);
if (ret < 0)
return NULL;
objects = object_hash->object_buckets[ret];
if (object >= objects->num_objects)
return NULL;
return objects->objects[object];
}
const struct uverbs_method_spec *uverbs_get_method(const struct uverbs_object_spec *object,
uint16_t method)
{
const struct uverbs_method_spec_hash *methods;
int ret = uverbs_ns_idx(&method, object->num_buckets);
if (ret < 0)
return NULL;
methods = object->method_buckets[ret];
if (method >= methods->num_methods)
return NULL;
return methods->methods[method];
}
void uverbs_uobject_get(struct ib_uobject *uobject)
{
kref_get(&uobject->ref);
......
......@@ -45,12 +45,6 @@
struct ib_uverbs_device;
int uverbs_ns_idx(u16 *id, unsigned int ns_count);
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);
void uverbs_destroy_ufile_hw(struct ib_uverbs_file *ufile,
enum rdma_remove_reason reason);
......
......@@ -111,7 +111,6 @@ struct ib_uverbs_device {
struct mutex lists_mutex; /* protect lists */
struct list_head uverbs_file_list;
struct list_head uverbs_events_file_list;
struct uverbs_root_spec *specs_root;
struct uverbs_api *uapi;
};
......
This diff is collapsed.
......@@ -176,7 +176,6 @@ static void ib_uverbs_release_dev(struct kobject *kobj)
uverbs_destroy_api(dev->uapi);
cleanup_srcu_struct(&dev->disassociate_srcu);
uverbs_free_spec_tree(dev->specs_root);
kfree(dev);
}
......@@ -998,37 +997,12 @@ static CLASS_ATTR_STRING(abi_version, S_IRUGO,
static int ib_uverbs_create_uapi(struct ib_device *device,
struct ib_uverbs_device *uverbs_dev)
{
const struct uverbs_object_tree_def **specs;
struct uverbs_root_spec *specs_root;
unsigned int num_specs = 1;
struct uverbs_api *uapi;
unsigned int i;
if (device->driver_specs)
for (i = 0; device->driver_specs[i]; i++)
num_specs++;
specs = kmalloc_array(num_specs, sizeof(*specs), GFP_KERNEL);
if (!specs)
return -ENOMEM;
specs[0] = uverbs_default_get_objects();
if (device->driver_specs)
for (i = 0; device->driver_specs[i]; i++)
specs[i+1] = device->driver_specs[i];
specs_root = uverbs_alloc_spec_tree(num_specs, specs);
kfree(specs);
if (IS_ERR(specs_root))
return PTR_ERR(specs_root);
uapi = uverbs_alloc_api(device->driver_specs, device->driver_id);
if (IS_ERR(uapi)) {
uverbs_free_spec_tree(specs_root);
if (IS_ERR(uapi))
return PTR_ERR(uapi);
}
uverbs_dev->specs_root = specs_root;
uverbs_dev->uapi = uapi;
return 0;
}
......
......@@ -114,46 +114,6 @@ struct uverbs_attr_spec {
} u2;
};
struct uverbs_attr_spec_hash {
size_t num_attrs;
unsigned long *mandatory_attrs_bitmask;
struct uverbs_attr_spec attrs[0];
};
struct uverbs_attr_bundle;
struct ib_uverbs_file;
struct uverbs_method_spec {
/* Combination of bits from enum UVERBS_ACTION_FLAG_XXXX */
u32 flags;
size_t num_buckets;
size_t num_child_attrs;
int (*handler)(struct ib_uverbs_file *ufile,
struct uverbs_attr_bundle *ctx);
struct uverbs_attr_spec_hash *attr_buckets[0];
};
struct uverbs_method_spec_hash {
size_t num_methods;
struct uverbs_method_spec *methods[0];
};
struct uverbs_object_spec {
const struct uverbs_obj_type *type_attrs;
size_t num_buckets;
struct uverbs_method_spec_hash *method_buckets[0];
};
struct uverbs_object_spec_hash {
size_t num_objects;
struct uverbs_object_spec *objects[0];
};
struct uverbs_root_spec {
size_t num_buckets;
struct uverbs_object_spec_hash *object_buckets[0];
};
/*
* Information about the API is loaded into a radix tree. For IOCTL we start
* with a tuple of:
......@@ -673,55 +633,4 @@ static inline __malloc void *uverbs_zalloc(struct uverbs_attr_bundle *bundle,
}
#endif
/* =================================================
* Definitions -> Specs infrastructure
* =================================================
*/
/*
* uverbs_alloc_spec_tree - Merges different common and driver specific feature
* into one parsing tree that every uverbs command will be parsed upon.
*
* @num_trees: Number of trees in the array @trees.
* @trees: Array of pointers to tree root definitions to merge. Each such tree
* possibly contains objects, methods and attributes definitions.
*
* Returns:
* uverbs_root_spec *: The root of the merged parsing tree.
* On error, we return an error code. Error is checked via IS_ERR.
*
* The following merges could take place:
* a. Two trees representing the same method with different handler
* -> We take the handler of the tree that its handler != NULL
* and its index in the trees array is greater. The incentive for that
* is that developers are expected to first merge common trees and then
* merge trees that gives specialized the behaviour.
* b. Two trees representing the same object with different
* type_attrs (struct uverbs_obj_type):
* -> We take the type_attrs of the tree that its type_attr != NULL
* and its index in the trees array is greater. This could be used
* in order to override the free function, allocation size, etc.
* c. Two trees representing the same method attribute (same id but possibly
* different attributes):
* -> ERROR (-ENOENT), we believe that's not the programmer's intent.
*
* An object without any methods is considered invalid and will abort the
* function with -ENOENT error.
*/
#if IS_ENABLED(CONFIG_INFINIBAND_USER_ACCESS)
struct uverbs_root_spec *uverbs_alloc_spec_tree(unsigned int num_trees,
const struct uverbs_object_tree_def **trees);
void uverbs_free_spec_tree(struct uverbs_root_spec *root);
#else
static inline struct uverbs_root_spec *uverbs_alloc_spec_tree(unsigned int num_trees,
const struct uverbs_object_tree_def **trees)
{
return NULL;
}
static inline void uverbs_free_spec_tree(struct uverbs_root_spec *root)
{
}
#endif
#endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment