Commit 0cbf432d authored by Jason Gunthorpe's avatar Jason Gunthorpe

RDMA/uverbs: Use a linear list to describe the compiled-in uapi

The 'tree' data structure is very hard to build at compile time, and this
makes it very limited. The new radix tree based compiler can handle a more
complex input language that does not require the compiler to perfectly
group everything into a neat tree structure.

Instead use a simple list to describe to input, where the list elements
can be of various different 'opcodes' instructing the radix compiler what
to do. Start out with opcodes chaining to other definition lists and
chaining to the existing 'tree' definition.

Replace the very top level of the 'object tree' with this list type and
get rid of struct uverbs_object_tree_def and DECLARE_UVERBS_OBJECT_TREE.
Signed-off-by: default avatarJason Gunthorpe <jgg@mellanox.com>
Signed-off-by: default avatarLeon Romanovsky <leonro@mellanox.com>
parent dfb631a1
...@@ -152,9 +152,8 @@ uapi_get_object(struct uverbs_api *uapi, u16 object_id) ...@@ -152,9 +152,8 @@ uapi_get_object(struct uverbs_api *uapi, u16 object_id)
} }
char *uapi_key_format(char *S, unsigned int key); char *uapi_key_format(char *S, unsigned int key);
struct uverbs_api *uverbs_alloc_api( struct uverbs_api *uverbs_alloc_api(const struct uapi_definition *driver_def,
const struct uverbs_object_tree_def *const *driver_specs, enum rdma_driver_id driver_id);
enum rdma_driver_id driver_id);
void uverbs_disassociate_api_pre(struct ib_uverbs_device *uverbs_dev); void uverbs_disassociate_api_pre(struct ib_uverbs_device *uverbs_dev);
void uverbs_disassociate_api(struct uverbs_api *uapi); void uverbs_disassociate_api(struct uverbs_api *uapi);
void uverbs_destroy_api(struct uverbs_api *uapi); void uverbs_destroy_api(struct uverbs_api *uapi);
...@@ -162,4 +161,6 @@ void uapi_compute_bundle_size(struct uverbs_api_ioctl_method *method_elm, ...@@ -162,4 +161,6 @@ void uapi_compute_bundle_size(struct uverbs_api_ioctl_method *method_elm,
unsigned int num_attrs); unsigned int num_attrs);
void uverbs_user_mmap_disassociate(struct ib_uverbs_file *ufile); void uverbs_user_mmap_disassociate(struct ib_uverbs_file *ufile);
extern const struct uapi_definition uverbs_def_obj_intf[];
#endif /* RDMA_CORE_H */ #endif /* RDMA_CORE_H */
...@@ -1224,7 +1224,7 @@ static int ib_uverbs_create_uapi(struct ib_device *device, ...@@ -1224,7 +1224,7 @@ static int ib_uverbs_create_uapi(struct ib_device *device,
{ {
struct uverbs_api *uapi; struct uverbs_api *uapi;
uapi = uverbs_alloc_api(device->driver_specs, device->driver_id); uapi = uverbs_alloc_api(device->driver_def, device->driver_id);
if (IS_ERR(uapi)) if (IS_ERR(uapi))
return PTR_ERR(uapi); return PTR_ERR(uapi);
......
...@@ -262,25 +262,22 @@ DECLARE_UVERBS_NAMED_OBJECT(UVERBS_OBJECT_PD, ...@@ -262,25 +262,22 @@ DECLARE_UVERBS_NAMED_OBJECT(UVERBS_OBJECT_PD,
DECLARE_UVERBS_GLOBAL_METHODS(UVERBS_OBJECT_DEVICE); DECLARE_UVERBS_GLOBAL_METHODS(UVERBS_OBJECT_DEVICE);
DECLARE_UVERBS_OBJECT_TREE(uverbs_default_objects, const struct uapi_definition uverbs_def_obj_intf[] = {
&UVERBS_OBJECT(UVERBS_OBJECT_DEVICE), UAPI_DEF_CHAIN_OBJ_TREE_NAMED(UVERBS_OBJECT_DEVICE),
&UVERBS_OBJECT(UVERBS_OBJECT_PD), UAPI_DEF_CHAIN_OBJ_TREE_NAMED(UVERBS_OBJECT_PD),
&UVERBS_OBJECT(UVERBS_OBJECT_MR), UAPI_DEF_CHAIN_OBJ_TREE_NAMED(UVERBS_OBJECT_MR),
&UVERBS_OBJECT(UVERBS_OBJECT_COMP_CHANNEL), UAPI_DEF_CHAIN_OBJ_TREE_NAMED(UVERBS_OBJECT_COMP_CHANNEL),
&UVERBS_OBJECT(UVERBS_OBJECT_CQ), UAPI_DEF_CHAIN_OBJ_TREE_NAMED(UVERBS_OBJECT_CQ),
&UVERBS_OBJECT(UVERBS_OBJECT_QP), UAPI_DEF_CHAIN_OBJ_TREE_NAMED(UVERBS_OBJECT_QP),
&UVERBS_OBJECT(UVERBS_OBJECT_AH), UAPI_DEF_CHAIN_OBJ_TREE_NAMED(UVERBS_OBJECT_AH),
&UVERBS_OBJECT(UVERBS_OBJECT_MW), UAPI_DEF_CHAIN_OBJ_TREE_NAMED(UVERBS_OBJECT_MW),
&UVERBS_OBJECT(UVERBS_OBJECT_SRQ), UAPI_DEF_CHAIN_OBJ_TREE_NAMED(UVERBS_OBJECT_SRQ),
&UVERBS_OBJECT(UVERBS_OBJECT_FLOW), UAPI_DEF_CHAIN_OBJ_TREE_NAMED(UVERBS_OBJECT_FLOW),
&UVERBS_OBJECT(UVERBS_OBJECT_WQ), UAPI_DEF_CHAIN_OBJ_TREE_NAMED(UVERBS_OBJECT_WQ),
&UVERBS_OBJECT(UVERBS_OBJECT_RWQ_IND_TBL), UAPI_DEF_CHAIN_OBJ_TREE_NAMED(UVERBS_OBJECT_RWQ_IND_TBL),
&UVERBS_OBJECT(UVERBS_OBJECT_XRCD), UAPI_DEF_CHAIN_OBJ_TREE_NAMED(UVERBS_OBJECT_XRCD),
&UVERBS_OBJECT(UVERBS_OBJECT_FLOW_ACTION), UAPI_DEF_CHAIN_OBJ_TREE_NAMED(UVERBS_OBJECT_FLOW_ACTION),
&UVERBS_OBJECT(UVERBS_OBJECT_DM), UAPI_DEF_CHAIN_OBJ_TREE_NAMED(UVERBS_OBJECT_DM),
&UVERBS_OBJECT(UVERBS_OBJECT_COUNTERS)); UAPI_DEF_CHAIN_OBJ_TREE_NAMED(UVERBS_OBJECT_COUNTERS),
{}
const struct uverbs_object_tree_def *uverbs_default_get_objects(void) };
{
return &uverbs_default_objects;
}
...@@ -98,72 +98,96 @@ static int uapi_merge_method(struct uverbs_api *uapi, ...@@ -98,72 +98,96 @@ static int uapi_merge_method(struct uverbs_api *uapi,
return 0; return 0;
} }
static int uapi_merge_tree(struct uverbs_api *uapi, static int uapi_merge_obj_tree(struct uverbs_api *uapi,
const struct uverbs_object_tree_def *tree, const struct uverbs_object_def *obj,
bool is_driver) bool is_driver)
{ {
unsigned int i, j; struct uverbs_api_object *obj_elm;
unsigned int i;
u32 obj_key;
int rc; int rc;
if (!tree->objects) obj_key = uapi_key_obj(obj->id);
obj_elm = uapi_add_elm(uapi, obj_key, sizeof(*obj_elm));
if (IS_ERR(obj_elm)) {
if (obj_elm != ERR_PTR(-EEXIST))
return PTR_ERR(obj_elm);
/* This occurs when a driver uses ADD_UVERBS_METHODS */
if (WARN_ON(obj->type_attrs))
return -EINVAL;
obj_elm = radix_tree_lookup(&uapi->radix, obj_key);
if (WARN_ON(!obj_elm))
return -EINVAL;
} else {
obj_elm->type_attrs = obj->type_attrs;
if (obj->type_attrs) {
obj_elm->type_class = obj->type_attrs->type_class;
/*
* Today drivers are only permitted to use idr_class
* types. They cannot use FD types because we
* currently have no way to revoke the fops pointer
* after device disassociation.
*/
if (WARN_ON(is_driver && obj->type_attrs->type_class !=
&uverbs_idr_class))
return -EINVAL;
}
}
if (!obj->methods)
return 0; return 0;
for (i = 0; i != tree->num_objects; i++) { for (i = 0; i != obj->num_methods; i++) {
const struct uverbs_object_def *obj = (*tree->objects)[i]; const struct uverbs_method_def *method = (*obj->methods)[i];
struct uverbs_api_object *obj_elm;
u32 obj_key;
if (!obj) if (!method)
continue; continue;
obj_key = uapi_key_obj(obj->id); rc = uapi_merge_method(uapi, obj_elm, obj_key, method,
obj_elm = uapi_add_elm(uapi, obj_key, sizeof(*obj_elm)); is_driver);
if (IS_ERR(obj_elm)) { if (rc)
if (obj_elm != ERR_PTR(-EEXIST)) return rc;
return PTR_ERR(obj_elm); }
/* This occurs when a driver uses ADD_UVERBS_METHODS */ return 0;
if (WARN_ON(obj->type_attrs)) }
return -EINVAL;
obj_elm = radix_tree_lookup(&uapi->radix, obj_key); static int uapi_merge_def(struct uverbs_api *uapi,
if (WARN_ON(!obj_elm)) const struct uapi_definition *def_list,
return -EINVAL; bool is_driver)
} else { {
obj_elm->type_attrs = obj->type_attrs; const struct uapi_definition *def = def_list;
if (obj->type_attrs) { int rc;
obj_elm->type_class =
obj->type_attrs->type_class; if (!def_list)
/* return 0;
* Today drivers are only permitted to use
* idr_class types. They cannot use FD types
* because we currently have no way to revoke
* the fops pointer after device
* disassociation.
*/
if (WARN_ON(is_driver &&
obj->type_attrs->type_class !=
&uverbs_idr_class))
return -EINVAL;
}
}
if (!obj->methods) for (;; def++) {
switch ((enum uapi_definition_kind)def->kind) {
case UAPI_DEF_CHAIN:
rc = uapi_merge_def(uapi, def->chain, is_driver);
if (rc)
return rc;
continue; continue;
for (j = 0; j != obj->num_methods; j++) { case UAPI_DEF_CHAIN_OBJ_TREE:
const struct uverbs_method_def *method = if (WARN_ON(def->object_start.object_id !=
(*obj->methods)[j]; def->chain_obj_tree->id))
if (!method) return -EINVAL;
continue;
rc = uapi_merge_method(uapi, obj_elm, obj_key, method, rc = uapi_merge_obj_tree(uapi, def->chain_obj_tree,
is_driver); is_driver);
if (rc) if (rc)
return rc; return rc;
continue;
case UAPI_DEF_END:
return 0;
} }
WARN_ON(true);
return -EINVAL;
} }
return 0;
} }
static int static int
...@@ -263,9 +287,13 @@ void uverbs_destroy_api(struct uverbs_api *uapi) ...@@ -263,9 +287,13 @@ void uverbs_destroy_api(struct uverbs_api *uapi)
kfree(uapi); kfree(uapi);
} }
struct uverbs_api *uverbs_alloc_api( static const struct uapi_definition uverbs_core_api[] = {
const struct uverbs_object_tree_def *const *driver_specs, UAPI_DEF_CHAIN(uverbs_def_obj_intf),
enum rdma_driver_id driver_id) {},
};
struct uverbs_api *uverbs_alloc_api(const struct uapi_definition *driver_def,
enum rdma_driver_id driver_id)
{ {
struct uverbs_api *uapi; struct uverbs_api *uapi;
int rc; int rc;
...@@ -277,15 +305,12 @@ struct uverbs_api *uverbs_alloc_api( ...@@ -277,15 +305,12 @@ struct uverbs_api *uverbs_alloc_api(
INIT_RADIX_TREE(&uapi->radix, GFP_KERNEL); INIT_RADIX_TREE(&uapi->radix, GFP_KERNEL);
uapi->driver_id = driver_id; uapi->driver_id = driver_id;
rc = uapi_merge_tree(uapi, uverbs_default_get_objects(), false); rc = uapi_merge_def(uapi, uverbs_core_api, false);
if (rc)
goto err;
rc = uapi_merge_def(uapi, driver_def, true);
if (rc) if (rc)
goto err; goto err;
for (; driver_specs && *driver_specs; driver_specs++) {
rc = uapi_merge_tree(uapi, *driver_specs, true);
if (rc)
goto err;
}
rc = uapi_finalize(uapi); rc = uapi_finalize(uapi);
if (rc) if (rc)
......
...@@ -1323,12 +1323,9 @@ DECLARE_UVERBS_NAMED_OBJECT(MLX5_IB_OBJECT_DEVX_UMEM, ...@@ -1323,12 +1323,9 @@ DECLARE_UVERBS_NAMED_OBJECT(MLX5_IB_OBJECT_DEVX_UMEM,
&UVERBS_METHOD(MLX5_IB_METHOD_DEVX_UMEM_REG), &UVERBS_METHOD(MLX5_IB_METHOD_DEVX_UMEM_REG),
&UVERBS_METHOD(MLX5_IB_METHOD_DEVX_UMEM_DEREG)); &UVERBS_METHOD(MLX5_IB_METHOD_DEVX_UMEM_DEREG));
DECLARE_UVERBS_OBJECT_TREE(devx_objects, const struct uapi_definition mlx5_ib_devx_defs[] = {
&UVERBS_OBJECT(MLX5_IB_OBJECT_DEVX), UAPI_DEF_CHAIN_OBJ_TREE_NAMED(MLX5_IB_OBJECT_DEVX),
&UVERBS_OBJECT(MLX5_IB_OBJECT_DEVX_OBJ), UAPI_DEF_CHAIN_OBJ_TREE_NAMED(MLX5_IB_OBJECT_DEVX_OBJ),
&UVERBS_OBJECT(MLX5_IB_OBJECT_DEVX_UMEM)); UAPI_DEF_CHAIN_OBJ_TREE_NAMED(MLX5_IB_OBJECT_DEVX_UMEM),
{},
const struct uverbs_object_tree_def *mlx5_ib_get_devx_tree(void) };
{
return &devx_objects;
}
...@@ -610,16 +610,10 @@ DECLARE_UVERBS_NAMED_OBJECT(MLX5_IB_OBJECT_FLOW_MATCHER, ...@@ -610,16 +610,10 @@ DECLARE_UVERBS_NAMED_OBJECT(MLX5_IB_OBJECT_FLOW_MATCHER,
&UVERBS_METHOD(MLX5_IB_METHOD_FLOW_MATCHER_CREATE), &UVERBS_METHOD(MLX5_IB_METHOD_FLOW_MATCHER_CREATE),
&UVERBS_METHOD(MLX5_IB_METHOD_FLOW_MATCHER_DESTROY)); &UVERBS_METHOD(MLX5_IB_METHOD_FLOW_MATCHER_DESTROY));
DECLARE_UVERBS_OBJECT_TREE(flow_objects, const struct uapi_definition mlx5_ib_flow_defs[] = {
&UVERBS_OBJECT(MLX5_IB_OBJECT_FLOW_MATCHER)); UAPI_DEF_CHAIN_OBJ_TREE_NAMED(MLX5_IB_OBJECT_FLOW_MATCHER),
UAPI_DEF_CHAIN_OBJ_TREE(UVERBS_OBJECT_FLOW, &mlx5_ib_fs),
int mlx5_ib_get_flow_trees(const struct uverbs_object_tree_def **root) UAPI_DEF_CHAIN_OBJ_TREE(UVERBS_OBJECT_FLOW_ACTION,
{ &mlx5_ib_flow_actions),
int i = 0; {},
};
root[i++] = &flow_objects;
root[i++] = &mlx5_ib_fs;
root[i++] = &mlx5_ib_flow_actions;
return i;
}
...@@ -5550,23 +5550,34 @@ ADD_UVERBS_ATTRIBUTES_SIMPLE( ...@@ -5550,23 +5550,34 @@ ADD_UVERBS_ATTRIBUTES_SIMPLE(
UVERBS_ATTR_FLAGS_IN(MLX5_IB_ATTR_CREATE_FLOW_ACTION_FLAGS, UVERBS_ATTR_FLAGS_IN(MLX5_IB_ATTR_CREATE_FLOW_ACTION_FLAGS,
enum mlx5_ib_uapi_flow_action_flags)); enum mlx5_ib_uapi_flow_action_flags));
static const struct uapi_definition mlx5_ib_defs[] = {
#if IS_ENABLED(CONFIG_INFINIBAND_USER_ACCESS)
UAPI_DEF_CHAIN(mlx5_ib_flow_defs),
#endif
UAPI_DEF_CHAIN_OBJ_TREE(UVERBS_OBJECT_FLOW_ACTION,
&mlx5_ib_flow_action),
UAPI_DEF_CHAIN_OBJ_TREE(UVERBS_OBJECT_DM, &mlx5_ib_dm),
{}
};
static int populate_specs_root(struct mlx5_ib_dev *dev) static int populate_specs_root(struct mlx5_ib_dev *dev)
{ {
const struct uverbs_object_tree_def **trees = dev->driver_trees; struct uapi_definition *defs = dev->driver_defs;
size_t num_trees = 0;
trees[num_trees++] = &mlx5_ib_flow_action;
trees[num_trees++] = &mlx5_ib_dm;
#if IS_ENABLED(CONFIG_INFINIBAND_USER_ACCESS)
if (MLX5_CAP_GEN_64(dev->mdev, general_obj_types) & if (MLX5_CAP_GEN_64(dev->mdev, general_obj_types) &
MLX5_GENERAL_OBJ_TYPES_CAP_UCTX) MLX5_GENERAL_OBJ_TYPES_CAP_UCTX)
trees[num_trees++] = mlx5_ib_get_devx_tree(); *defs++ = (struct uapi_definition)UAPI_DEF_CHAIN(
mlx5_ib_devx_defs);
#endif
num_trees += mlx5_ib_get_flow_trees(trees + num_trees); *defs++ = (struct uapi_definition)UAPI_DEF_CHAIN(mlx5_ib_defs);
*defs++ = (struct uapi_definition){};
WARN_ON(defs - dev->driver_defs >= ARRAY_SIZE(dev->driver_defs));
WARN_ON(num_trees >= ARRAY_SIZE(dev->driver_trees)); if (IS_ENABLED(CONFIG_INFINIBAND_USER_ACCESS))
trees[num_trees] = NULL; dev->ib_dev.driver_def = dev->driver_defs;
dev->ib_dev.driver_specs = trees;
return 0; return 0;
} }
......
...@@ -891,7 +891,7 @@ struct mlx5_ib_pf_eq { ...@@ -891,7 +891,7 @@ struct mlx5_ib_pf_eq {
struct mlx5_ib_dev { struct mlx5_ib_dev {
struct ib_device ib_dev; struct ib_device ib_dev;
const struct uverbs_object_tree_def *driver_trees[7]; struct uapi_definition driver_defs[7];
struct mlx5_core_dev *mdev; struct mlx5_core_dev *mdev;
struct mlx5_roce roce[MLX5_MAX_PORTS]; struct mlx5_roce roce[MLX5_MAX_PORTS];
int num_ports; int num_ports;
...@@ -1264,29 +1264,23 @@ void mlx5_ib_put_native_port_mdev(struct mlx5_ib_dev *dev, ...@@ -1264,29 +1264,23 @@ void mlx5_ib_put_native_port_mdev(struct mlx5_ib_dev *dev,
int mlx5_ib_devx_create(struct mlx5_ib_dev *dev); int mlx5_ib_devx_create(struct mlx5_ib_dev *dev);
void mlx5_ib_devx_destroy(struct mlx5_ib_dev *dev, u16 uid); void mlx5_ib_devx_destroy(struct mlx5_ib_dev *dev, u16 uid);
const struct uverbs_object_tree_def *mlx5_ib_get_devx_tree(void); const struct uverbs_object_tree_def *mlx5_ib_get_devx_tree(void);
extern const struct uapi_definition mlx5_ib_devx_defs[];
extern const struct uapi_definition mlx5_ib_flow_defs[];
struct mlx5_ib_flow_handler *mlx5_ib_raw_fs_rule_add( struct mlx5_ib_flow_handler *mlx5_ib_raw_fs_rule_add(
struct mlx5_ib_dev *dev, struct mlx5_ib_flow_matcher *fs_matcher, struct mlx5_ib_dev *dev, struct mlx5_ib_flow_matcher *fs_matcher,
struct mlx5_flow_act *flow_act, void *cmd_in, int inlen, struct mlx5_flow_act *flow_act, void *cmd_in, int inlen,
int dest_id, int dest_type); int dest_id, int dest_type);
bool mlx5_ib_devx_is_flow_dest(void *obj, int *dest_id, int *dest_type); bool mlx5_ib_devx_is_flow_dest(void *obj, int *dest_id, int *dest_type);
int mlx5_ib_get_flow_trees(const struct uverbs_object_tree_def **root);
void mlx5_ib_destroy_flow_action_raw(struct mlx5_ib_flow_action *maction); void mlx5_ib_destroy_flow_action_raw(struct mlx5_ib_flow_action *maction);
#else #else
static inline int static inline int
mlx5_ib_devx_create(struct mlx5_ib_dev *dev) { return -EOPNOTSUPP; }; mlx5_ib_devx_create(struct mlx5_ib_dev *dev) { return -EOPNOTSUPP; };
static inline void mlx5_ib_devx_destroy(struct mlx5_ib_dev *dev, u16 uid) {} static inline void mlx5_ib_devx_destroy(struct mlx5_ib_dev *dev, u16 uid) {}
static inline const struct uverbs_object_tree_def *
mlx5_ib_get_devx_tree(void) { return NULL; }
static inline bool mlx5_ib_devx_is_flow_dest(void *obj, int *dest_id, static inline bool mlx5_ib_devx_is_flow_dest(void *obj, int *dest_id,
int *dest_type) int *dest_type)
{ {
return false; return false;
} }
static inline int
mlx5_ib_get_flow_trees(const struct uverbs_object_tree_def **root)
{
return 0;
}
static inline void static inline void
mlx5_ib_destroy_flow_action_raw(struct mlx5_ib_flow_action *maction) mlx5_ib_destroy_flow_action_raw(struct mlx5_ib_flow_action *maction)
{ {
......
...@@ -2600,7 +2600,7 @@ struct ib_device { ...@@ -2600,7 +2600,7 @@ struct ib_device {
const struct cpumask *(*get_vector_affinity)(struct ib_device *ibdev, const struct cpumask *(*get_vector_affinity)(struct ib_device *ibdev,
int comp_vector); int comp_vector);
const struct uverbs_object_tree_def *const *driver_specs; const struct uapi_definition *driver_def;
enum rdma_driver_id driver_id; enum rdma_driver_id driver_id;
}; };
......
...@@ -296,11 +296,43 @@ struct uverbs_object_def { ...@@ -296,11 +296,43 @@ struct uverbs_object_def {
const struct uverbs_method_def * const (*methods)[]; const struct uverbs_method_def * const (*methods)[];
}; };
struct uverbs_object_tree_def { enum uapi_definition_kind {
size_t num_objects; UAPI_DEF_END = 0,
const struct uverbs_object_def * const (*objects)[]; UAPI_DEF_CHAIN_OBJ_TREE,
UAPI_DEF_CHAIN,
}; };
struct uapi_definition {
u8 kind;
union {
struct {
u16 object_id;
} object_start;
};
union {
const struct uapi_definition *chain;
const struct uverbs_object_def *chain_obj_tree;
};
};
/* Include another struct uapi_definition in this one */
#define UAPI_DEF_CHAIN(_def_var) \
{ \
.kind = UAPI_DEF_CHAIN, .chain = _def_var, \
}
/* Temporary until the tree base description is replaced */
#define UAPI_DEF_CHAIN_OBJ_TREE(_object_enum, _object_ptr) \
{ \
.kind = UAPI_DEF_CHAIN_OBJ_TREE, \
.object_start = { .object_id = _object_enum }, \
.chain_obj_tree = _object_ptr, \
}
#define UAPI_DEF_CHAIN_OBJ_TREE_NAMED(_object_enum, ...) \
UAPI_DEF_CHAIN_OBJ_TREE(_object_enum, &UVERBS_OBJECT(_object_enum)), \
##__VA_ARGS__
/* /*
* ======================================= * =======================================
* Attribute Specifications * Attribute Specifications
...@@ -438,21 +470,6 @@ struct uverbs_object_tree_def { ...@@ -438,21 +470,6 @@ struct uverbs_object_tree_def {
UVERBS_ATTR_MIN_SIZE(0), \ UVERBS_ATTR_MIN_SIZE(0), \
UA_OPTIONAL) UA_OPTIONAL)
/*
* =======================================
* Declaration helpers
* =======================================
*/
#define DECLARE_UVERBS_OBJECT_TREE(_name, ...) \
static const struct uverbs_object_def *const _name##_ptr[] = { \
__VA_ARGS__, \
}; \
static const struct uverbs_object_tree_def _name = { \
.num_objects = ARRAY_SIZE(_name##_ptr), \
.objects = &_name##_ptr, \
}
/* ================================================= /* =================================================
* Parsing infrastructure * Parsing infrastructure
* ================================================= * =================================================
......
...@@ -102,18 +102,11 @@ ...@@ -102,18 +102,11 @@
#define ADD_UVERBS_METHODS(_name, _object_id, ...) \ #define ADD_UVERBS_METHODS(_name, _object_id, ...) \
static const struct uverbs_method_def *const UVERBS_OBJECT_METHODS( \ static const struct uverbs_method_def *const UVERBS_OBJECT_METHODS( \
_object_id)[] = { __VA_ARGS__ }; \ _object_id)[] = { __VA_ARGS__ }; \
static const struct uverbs_object_def _name##_struct = { \ static const struct uverbs_object_def _name = { \
.id = _object_id, \ .id = _object_id, \
.num_methods = ARRAY_SIZE(UVERBS_OBJECT_METHODS(_object_id)), \ .num_methods = ARRAY_SIZE(UVERBS_OBJECT_METHODS(_object_id)), \
.methods = &UVERBS_OBJECT_METHODS(_object_id) \ .methods = &UVERBS_OBJECT_METHODS(_object_id) \
}; \ };
static const struct uverbs_object_def *const _name##_ptrs[] = { \
&_name##_struct, \
}; \
static const struct uverbs_object_tree_def _name = { \
.num_objects = 1, \
.objects = &_name##_ptrs, \
}
/* Used by drivers to declare a complete parsing tree for a single method that /* Used by drivers to declare a complete parsing tree for a single method that
* differs only in having additional driver specific attributes. * differs only in having additional driver specific attributes.
......
...@@ -37,15 +37,6 @@ ...@@ -37,15 +37,6 @@
#include <rdma/uverbs_ioctl.h> #include <rdma/uverbs_ioctl.h>
#include <rdma/ib_user_ioctl_verbs.h> #include <rdma/ib_user_ioctl_verbs.h>
#if IS_ENABLED(CONFIG_INFINIBAND_USER_ACCESS)
const struct uverbs_object_tree_def *uverbs_default_get_objects(void);
#else
static inline const struct uverbs_object_tree_def *uverbs_default_get_objects(void)
{
return NULL;
}
#endif
/* Returns _id, or causes a compile error if _id is not a u32. /* Returns _id, or causes a compile error if _id is not a u32.
* *
* The uobj APIs should only be used with the write based uAPI to access * The uobj APIs should only be used with the write based uAPI to access
......
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