RDMA/uverbs: Simplify UVERBS_ATTR family of macros
Instead of using a complex cascade of macros, just directly provide the initializer list each of the declarations is trying to create. Now that the macros are simplified this also reworks the uverbs_attr_spec to be friendly to older compilers by eliminating any unnamed structures/unions inside, and removing the duplication of some fields. The structure size remains at 16 bytes which was the original motivation for some of this oddness. Signed-off-by: Jason Gunthorpe <jgg@mellanox.com> Signed-off-by: Leon Romanovsky <leonro@mellanox.com>
This commit is contained in:
parent
ad544cfe54
commit
d108dac080
|
@ -77,13 +77,13 @@ static int uverbs_process_attr(struct ib_uverbs_file *ufile,
|
||||||
|
|
||||||
switch (spec->type) {
|
switch (spec->type) {
|
||||||
case UVERBS_ATTR_TYPE_ENUM_IN:
|
case UVERBS_ATTR_TYPE_ENUM_IN:
|
||||||
if (uattr->attr_data.enum_data.elem_id >= spec->enum_def.num_elems)
|
if (uattr->attr_data.enum_data.elem_id >= spec->u.enum_def.num_elems)
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
if (uattr->attr_data.enum_data.reserved)
|
if (uattr->attr_data.enum_data.reserved)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
val_spec = &spec->enum_def.ids[uattr->attr_data.enum_data.elem_id];
|
val_spec = &spec->u2.enum_def.ids[uattr->attr_data.enum_data.elem_id];
|
||||||
|
|
||||||
/* Currently we only support PTR_IN based enums */
|
/* Currently we only support PTR_IN based enums */
|
||||||
if (val_spec->type != UVERBS_ATTR_TYPE_PTR_IN)
|
if (val_spec->type != UVERBS_ATTR_TYPE_PTR_IN)
|
||||||
|
@ -97,16 +97,16 @@ static int uverbs_process_attr(struct ib_uverbs_file *ufile,
|
||||||
* longer struct will fail here if used with an old kernel and
|
* longer struct will fail here if used with an old kernel and
|
||||||
* non-zero content, making ABI compat/discovery simpler.
|
* non-zero content, making ABI compat/discovery simpler.
|
||||||
*/
|
*/
|
||||||
if (uattr->len > val_spec->ptr.len &&
|
if (uattr->len > val_spec->u.ptr.len &&
|
||||||
val_spec->flags & UVERBS_ATTR_SPEC_F_MIN_SZ_OR_ZERO &&
|
val_spec->flags & UVERBS_ATTR_SPEC_F_MIN_SZ_OR_ZERO &&
|
||||||
!uverbs_is_attr_cleared(uattr, val_spec->ptr.len))
|
!uverbs_is_attr_cleared(uattr, val_spec->u.ptr.len))
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
/* fall through */
|
/* fall through */
|
||||||
case UVERBS_ATTR_TYPE_PTR_OUT:
|
case UVERBS_ATTR_TYPE_PTR_OUT:
|
||||||
if (uattr->len < val_spec->ptr.min_len ||
|
if (uattr->len < val_spec->u.ptr.min_len ||
|
||||||
(!(val_spec->flags & UVERBS_ATTR_SPEC_F_MIN_SZ_OR_ZERO) &&
|
(!(val_spec->flags & UVERBS_ATTR_SPEC_F_MIN_SZ_OR_ZERO) &&
|
||||||
uattr->len > val_spec->ptr.len))
|
uattr->len > val_spec->u.ptr.len))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (spec->type != UVERBS_ATTR_TYPE_ENUM_IN &&
|
if (spec->type != UVERBS_ATTR_TYPE_ENUM_IN &&
|
||||||
|
@ -149,20 +149,20 @@ static int uverbs_process_attr(struct ib_uverbs_file *ufile,
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
o_attr = &e->obj_attr;
|
o_attr = &e->obj_attr;
|
||||||
object = uverbs_get_object(ufile, spec->obj.obj_type);
|
object = uverbs_get_object(ufile, spec->u.obj.obj_type);
|
||||||
if (!object)
|
if (!object)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
o_attr->uobject = uverbs_get_uobject_from_context(
|
o_attr->uobject = uverbs_get_uobject_from_context(
|
||||||
object->type_attrs,
|
object->type_attrs,
|
||||||
ufile->ucontext,
|
ufile->ucontext,
|
||||||
spec->obj.access,
|
spec->u.obj.access,
|
||||||
(int)uattr->data);
|
(int)uattr->data);
|
||||||
|
|
||||||
if (IS_ERR(o_attr->uobject))
|
if (IS_ERR(o_attr->uobject))
|
||||||
return PTR_ERR(o_attr->uobject);
|
return PTR_ERR(o_attr->uobject);
|
||||||
|
|
||||||
if (spec->obj.access == UVERBS_ACCESS_NEW) {
|
if (spec->u.obj.access == UVERBS_ACCESS_NEW) {
|
||||||
u64 id = o_attr->uobject->id;
|
u64 id = o_attr->uobject->id;
|
||||||
|
|
||||||
/* Copy the allocated id to the user-space */
|
/* Copy the allocated id to the user-space */
|
||||||
|
@ -216,7 +216,7 @@ static int uverbs_finalize_attrs(struct uverbs_attr_bundle *attrs_bundle,
|
||||||
|
|
||||||
current_ret = uverbs_finalize_object(
|
current_ret = uverbs_finalize_object(
|
||||||
attr->obj_attr.uobject,
|
attr->obj_attr.uobject,
|
||||||
spec->obj.access, commit);
|
spec->u.obj.access, commit);
|
||||||
if (!ret)
|
if (!ret)
|
||||||
ret = current_ret;
|
ret = current_ret;
|
||||||
} else if (spec->type == UVERBS_ATTR_TYPE_PTR_IN &&
|
} else if (spec->type == UVERBS_ATTR_TYPE_PTR_IN &&
|
||||||
|
|
|
@ -367,8 +367,8 @@ static struct uverbs_method_spec *build_method_with_attrs(const struct uverbs_me
|
||||||
memcpy(attr, &attr_defs[0]->attr, sizeof(*attr));
|
memcpy(attr, &attr_defs[0]->attr, sizeof(*attr));
|
||||||
|
|
||||||
attr_obj_with_special_access = IS_ATTR_OBJECT(attr) &&
|
attr_obj_with_special_access = IS_ATTR_OBJECT(attr) &&
|
||||||
(attr->obj.access == UVERBS_ACCESS_NEW ||
|
(attr->u.obj.access == UVERBS_ACCESS_NEW ||
|
||||||
attr->obj.access == UVERBS_ACCESS_DESTROY);
|
attr->u.obj.access == UVERBS_ACCESS_DESTROY);
|
||||||
num_of_singularities += !!attr_obj_with_special_access;
|
num_of_singularities += !!attr_obj_with_special_access;
|
||||||
if (WARN(num_of_singularities > 1,
|
if (WARN(num_of_singularities > 1,
|
||||||
"ib_uverbs: Method contains more than one object attr (%d) with new/destroy access\n",
|
"ib_uverbs: Method contains more than one object attr (%d) with new/destroy access\n",
|
||||||
|
|
|
@ -222,11 +222,11 @@ int uverbs_destroy_def_handler(struct ib_device *ib_dev,
|
||||||
* spec.
|
* spec.
|
||||||
*/
|
*/
|
||||||
const struct uverbs_attr_def uverbs_uhw_compat_in =
|
const struct uverbs_attr_def uverbs_uhw_compat_in =
|
||||||
UVERBS_ATTR_PTR_IN_SZ(UVERBS_ATTR_UHW_IN, UVERBS_ATTR_MIN_SIZE(0),
|
UVERBS_ATTR_PTR_IN(UVERBS_ATTR_UHW_IN, UVERBS_ATTR_MIN_SIZE(0),
|
||||||
UA_FLAGS(UVERBS_ATTR_SPEC_F_MIN_SZ_OR_ZERO));
|
UA_FLAGS(UVERBS_ATTR_SPEC_F_MIN_SZ_OR_ZERO));
|
||||||
const struct uverbs_attr_def uverbs_uhw_compat_out =
|
const struct uverbs_attr_def uverbs_uhw_compat_out =
|
||||||
UVERBS_ATTR_PTR_OUT_SZ(UVERBS_ATTR_UHW_OUT, UVERBS_ATTR_MIN_SIZE(0),
|
UVERBS_ATTR_PTR_OUT(UVERBS_ATTR_UHW_OUT, UVERBS_ATTR_MIN_SIZE(0),
|
||||||
UA_FLAGS(UVERBS_ATTR_SPEC_F_MIN_SZ_OR_ZERO));
|
UA_FLAGS(UVERBS_ATTR_SPEC_F_MIN_SZ_OR_ZERO));
|
||||||
|
|
||||||
void create_udata(struct uverbs_attr_bundle *ctx, struct ib_udata *udata)
|
void create_udata(struct uverbs_attr_bundle *ctx, struct ib_udata *udata)
|
||||||
{
|
{
|
||||||
|
|
|
@ -366,28 +366,22 @@ static int UVERBS_HANDLER(UVERBS_METHOD_FLOW_ACTION_ESP_MODIFY)(struct ib_device
|
||||||
|
|
||||||
static const struct uverbs_attr_spec uverbs_flow_action_esp_keymat[] = {
|
static const struct uverbs_attr_spec uverbs_flow_action_esp_keymat[] = {
|
||||||
[IB_UVERBS_FLOW_ACTION_ESP_KEYMAT_AES_GCM] = {
|
[IB_UVERBS_FLOW_ACTION_ESP_KEYMAT_AES_GCM] = {
|
||||||
{ .ptr = {
|
.type = UVERBS_ATTR_TYPE_PTR_IN,
|
||||||
.type = UVERBS_ATTR_TYPE_PTR_IN,
|
UVERBS_ATTR_TYPE(struct ib_uverbs_flow_action_esp_keymat_aes_gcm),
|
||||||
UVERBS_ATTR_TYPE(struct ib_uverbs_flow_action_esp_keymat_aes_gcm),
|
UA_FLAGS(UVERBS_ATTR_SPEC_F_MIN_SZ_OR_ZERO),
|
||||||
.flags = UVERBS_ATTR_SPEC_F_MIN_SZ_OR_ZERO,
|
|
||||||
} },
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct uverbs_attr_spec uverbs_flow_action_esp_replay[] = {
|
static const struct uverbs_attr_spec uverbs_flow_action_esp_replay[] = {
|
||||||
[IB_UVERBS_FLOW_ACTION_ESP_REPLAY_NONE] = {
|
[IB_UVERBS_FLOW_ACTION_ESP_REPLAY_NONE] = {
|
||||||
{ .ptr = {
|
.type = UVERBS_ATTR_TYPE_PTR_IN,
|
||||||
.type = UVERBS_ATTR_TYPE_PTR_IN,
|
/* No need to specify any data */
|
||||||
/* No need to specify any data */
|
UVERBS_ATTR_SIZE(0, 0),
|
||||||
.len = 0,
|
|
||||||
} }
|
|
||||||
},
|
},
|
||||||
[IB_UVERBS_FLOW_ACTION_ESP_REPLAY_BMP] = {
|
[IB_UVERBS_FLOW_ACTION_ESP_REPLAY_BMP] = {
|
||||||
{ .ptr = {
|
.type = UVERBS_ATTR_TYPE_PTR_IN,
|
||||||
.type = UVERBS_ATTR_TYPE_PTR_IN,
|
UVERBS_ATTR_STRUCT(struct ib_uverbs_flow_action_esp_replay_bmp, size),
|
||||||
UVERBS_ATTR_STRUCT(struct ib_uverbs_flow_action_esp_replay_bmp, size),
|
UA_FLAGS(UVERBS_ATTR_SPEC_F_MIN_SZ_OR_ZERO),
|
||||||
.flags = UVERBS_ATTR_SPEC_F_MIN_SZ_OR_ZERO,
|
|
||||||
} }
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1017,15 +1017,15 @@ static DECLARE_UVERBS_NAMED_METHOD(MLX5_IB_METHOD_DEVX_QUERY_UAR,
|
||||||
UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY)));
|
UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY)));
|
||||||
|
|
||||||
static DECLARE_UVERBS_NAMED_METHOD(MLX5_IB_METHOD_DEVX_OTHER,
|
static DECLARE_UVERBS_NAMED_METHOD(MLX5_IB_METHOD_DEVX_OTHER,
|
||||||
&UVERBS_ATTR_PTR_IN_SZ(MLX5_IB_ATTR_DEVX_OTHER_CMD_IN,
|
&UVERBS_ATTR_PTR_IN(MLX5_IB_ATTR_DEVX_OTHER_CMD_IN,
|
||||||
UVERBS_ATTR_MIN_SIZE(MLX5_ST_SZ_BYTES(general_obj_in_cmd_hdr)),
|
UVERBS_ATTR_MIN_SIZE(MLX5_ST_SZ_BYTES(general_obj_in_cmd_hdr)),
|
||||||
UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY |
|
UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY |
|
||||||
UVERBS_ATTR_SPEC_F_MIN_SZ_OR_ZERO |
|
UVERBS_ATTR_SPEC_F_MIN_SZ_OR_ZERO |
|
||||||
UVERBS_ATTR_SPEC_F_ALLOC_AND_COPY)),
|
UVERBS_ATTR_SPEC_F_ALLOC_AND_COPY)),
|
||||||
&UVERBS_ATTR_PTR_OUT_SZ(MLX5_IB_ATTR_DEVX_OTHER_CMD_OUT,
|
&UVERBS_ATTR_PTR_OUT(MLX5_IB_ATTR_DEVX_OTHER_CMD_OUT,
|
||||||
UVERBS_ATTR_MIN_SIZE(MLX5_ST_SZ_BYTES(general_obj_out_cmd_hdr)),
|
UVERBS_ATTR_MIN_SIZE(MLX5_ST_SZ_BYTES(general_obj_out_cmd_hdr)),
|
||||||
UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY |
|
UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY |
|
||||||
UVERBS_ATTR_SPEC_F_MIN_SZ_OR_ZERO))
|
UVERBS_ATTR_SPEC_F_MIN_SZ_OR_ZERO))
|
||||||
);
|
);
|
||||||
|
|
||||||
static DECLARE_UVERBS_NAMED_METHOD(MLX5_IB_METHOD_DEVX_OBJ_CREATE,
|
static DECLARE_UVERBS_NAMED_METHOD(MLX5_IB_METHOD_DEVX_OBJ_CREATE,
|
||||||
|
@ -1033,15 +1033,15 @@ static DECLARE_UVERBS_NAMED_METHOD(MLX5_IB_METHOD_DEVX_OBJ_CREATE,
|
||||||
MLX5_IB_OBJECT_DEVX_OBJ,
|
MLX5_IB_OBJECT_DEVX_OBJ,
|
||||||
UVERBS_ACCESS_NEW,
|
UVERBS_ACCESS_NEW,
|
||||||
UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY)),
|
UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY)),
|
||||||
&UVERBS_ATTR_PTR_IN_SZ(MLX5_IB_ATTR_DEVX_OBJ_CREATE_CMD_IN,
|
&UVERBS_ATTR_PTR_IN(MLX5_IB_ATTR_DEVX_OBJ_CREATE_CMD_IN,
|
||||||
UVERBS_ATTR_MIN_SIZE(MLX5_ST_SZ_BYTES(general_obj_in_cmd_hdr)),
|
UVERBS_ATTR_MIN_SIZE(MLX5_ST_SZ_BYTES(general_obj_in_cmd_hdr)),
|
||||||
UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY |
|
UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY |
|
||||||
UVERBS_ATTR_SPEC_F_MIN_SZ_OR_ZERO |
|
UVERBS_ATTR_SPEC_F_MIN_SZ_OR_ZERO |
|
||||||
UVERBS_ATTR_SPEC_F_ALLOC_AND_COPY)),
|
UVERBS_ATTR_SPEC_F_ALLOC_AND_COPY)),
|
||||||
&UVERBS_ATTR_PTR_OUT_SZ(MLX5_IB_ATTR_DEVX_OBJ_CREATE_CMD_OUT,
|
&UVERBS_ATTR_PTR_OUT(MLX5_IB_ATTR_DEVX_OBJ_CREATE_CMD_OUT,
|
||||||
UVERBS_ATTR_MIN_SIZE(MLX5_ST_SZ_BYTES(general_obj_out_cmd_hdr)),
|
UVERBS_ATTR_MIN_SIZE(MLX5_ST_SZ_BYTES(general_obj_out_cmd_hdr)),
|
||||||
UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY |
|
UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY |
|
||||||
UVERBS_ATTR_SPEC_F_MIN_SZ_OR_ZERO)));
|
UVERBS_ATTR_SPEC_F_MIN_SZ_OR_ZERO)));
|
||||||
|
|
||||||
static DECLARE_UVERBS_NAMED_METHOD(MLX5_IB_METHOD_DEVX_OBJ_DESTROY,
|
static DECLARE_UVERBS_NAMED_METHOD(MLX5_IB_METHOD_DEVX_OBJ_DESTROY,
|
||||||
&UVERBS_ATTR_IDR(MLX5_IB_ATTR_DEVX_OBJ_DESTROY_HANDLE,
|
&UVERBS_ATTR_IDR(MLX5_IB_ATTR_DEVX_OBJ_DESTROY_HANDLE,
|
||||||
|
@ -1054,30 +1054,30 @@ static DECLARE_UVERBS_NAMED_METHOD(MLX5_IB_METHOD_DEVX_OBJ_MODIFY,
|
||||||
MLX5_IB_OBJECT_DEVX_OBJ,
|
MLX5_IB_OBJECT_DEVX_OBJ,
|
||||||
UVERBS_ACCESS_WRITE,
|
UVERBS_ACCESS_WRITE,
|
||||||
UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY)),
|
UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY)),
|
||||||
&UVERBS_ATTR_PTR_IN_SZ(MLX5_IB_ATTR_DEVX_OBJ_MODIFY_CMD_IN,
|
&UVERBS_ATTR_PTR_IN(MLX5_IB_ATTR_DEVX_OBJ_MODIFY_CMD_IN,
|
||||||
UVERBS_ATTR_MIN_SIZE(MLX5_ST_SZ_BYTES(general_obj_in_cmd_hdr)),
|
UVERBS_ATTR_MIN_SIZE(MLX5_ST_SZ_BYTES(general_obj_in_cmd_hdr)),
|
||||||
UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY |
|
UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY |
|
||||||
UVERBS_ATTR_SPEC_F_MIN_SZ_OR_ZERO |
|
UVERBS_ATTR_SPEC_F_MIN_SZ_OR_ZERO |
|
||||||
UVERBS_ATTR_SPEC_F_ALLOC_AND_COPY)),
|
UVERBS_ATTR_SPEC_F_ALLOC_AND_COPY)),
|
||||||
&UVERBS_ATTR_PTR_OUT_SZ(MLX5_IB_ATTR_DEVX_OBJ_MODIFY_CMD_OUT,
|
&UVERBS_ATTR_PTR_OUT(MLX5_IB_ATTR_DEVX_OBJ_MODIFY_CMD_OUT,
|
||||||
UVERBS_ATTR_MIN_SIZE(MLX5_ST_SZ_BYTES(general_obj_out_cmd_hdr)),
|
UVERBS_ATTR_MIN_SIZE(MLX5_ST_SZ_BYTES(general_obj_out_cmd_hdr)),
|
||||||
UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY |
|
UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY |
|
||||||
UVERBS_ATTR_SPEC_F_MIN_SZ_OR_ZERO)));
|
UVERBS_ATTR_SPEC_F_MIN_SZ_OR_ZERO)));
|
||||||
|
|
||||||
static DECLARE_UVERBS_NAMED_METHOD(MLX5_IB_METHOD_DEVX_OBJ_QUERY,
|
static DECLARE_UVERBS_NAMED_METHOD(MLX5_IB_METHOD_DEVX_OBJ_QUERY,
|
||||||
&UVERBS_ATTR_IDR(MLX5_IB_ATTR_DEVX_OBJ_QUERY_HANDLE,
|
&UVERBS_ATTR_IDR(MLX5_IB_ATTR_DEVX_OBJ_QUERY_HANDLE,
|
||||||
MLX5_IB_OBJECT_DEVX_OBJ,
|
MLX5_IB_OBJECT_DEVX_OBJ,
|
||||||
UVERBS_ACCESS_READ,
|
UVERBS_ACCESS_READ,
|
||||||
UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY)),
|
UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY)),
|
||||||
&UVERBS_ATTR_PTR_IN_SZ(MLX5_IB_ATTR_DEVX_OBJ_QUERY_CMD_IN,
|
&UVERBS_ATTR_PTR_IN(MLX5_IB_ATTR_DEVX_OBJ_QUERY_CMD_IN,
|
||||||
UVERBS_ATTR_MIN_SIZE(MLX5_ST_SZ_BYTES(general_obj_in_cmd_hdr)),
|
UVERBS_ATTR_MIN_SIZE(MLX5_ST_SZ_BYTES(general_obj_in_cmd_hdr)),
|
||||||
UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY |
|
UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY |
|
||||||
UVERBS_ATTR_SPEC_F_MIN_SZ_OR_ZERO |
|
UVERBS_ATTR_SPEC_F_MIN_SZ_OR_ZERO |
|
||||||
UVERBS_ATTR_SPEC_F_ALLOC_AND_COPY)),
|
UVERBS_ATTR_SPEC_F_ALLOC_AND_COPY)),
|
||||||
&UVERBS_ATTR_PTR_OUT_SZ(MLX5_IB_ATTR_DEVX_OBJ_QUERY_CMD_OUT,
|
&UVERBS_ATTR_PTR_OUT(MLX5_IB_ATTR_DEVX_OBJ_QUERY_CMD_OUT,
|
||||||
UVERBS_ATTR_MIN_SIZE(MLX5_ST_SZ_BYTES(general_obj_out_cmd_hdr)),
|
UVERBS_ATTR_MIN_SIZE(MLX5_ST_SZ_BYTES(general_obj_out_cmd_hdr)),
|
||||||
UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY |
|
UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY |
|
||||||
UVERBS_ATTR_SPEC_F_MIN_SZ_OR_ZERO)));
|
UVERBS_ATTR_SPEC_F_MIN_SZ_OR_ZERO)));
|
||||||
|
|
||||||
static DECLARE_UVERBS_GLOBAL_METHODS(MLX5_IB_OBJECT_DEVX,
|
static DECLARE_UVERBS_GLOBAL_METHODS(MLX5_IB_OBJECT_DEVX,
|
||||||
&UVERBS_METHOD(MLX5_IB_METHOD_DEVX_OTHER),
|
&UVERBS_METHOD(MLX5_IB_METHOD_DEVX_OTHER),
|
||||||
|
|
|
@ -73,46 +73,42 @@ enum {
|
||||||
|
|
||||||
/* Specification of a single attribute inside the ioctl message */
|
/* Specification of a single attribute inside the ioctl message */
|
||||||
struct uverbs_attr_spec {
|
struct uverbs_attr_spec {
|
||||||
|
u8 type;
|
||||||
|
u8 flags;
|
||||||
|
|
||||||
union {
|
union {
|
||||||
/* Header shared by all following union members - to reduce space. */
|
|
||||||
struct {
|
struct {
|
||||||
enum uverbs_attr_type type;
|
|
||||||
/* Combination of bits from enum UVERBS_ATTR_SPEC_F_XXXX */
|
|
||||||
u8 flags;
|
|
||||||
};
|
|
||||||
struct {
|
|
||||||
enum uverbs_attr_type type;
|
|
||||||
/* Combination of bits from enum UVERBS_ATTR_SPEC_F_XXXX */
|
|
||||||
u8 flags;
|
|
||||||
/* Current known size to kernel */
|
/* Current known size to kernel */
|
||||||
u16 len;
|
u16 len;
|
||||||
/* User isn't allowed to provide something < min_len */
|
/* User isn't allowed to provide something < min_len */
|
||||||
u16 min_len;
|
u16 min_len;
|
||||||
} ptr;
|
} ptr;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
enum uverbs_attr_type type;
|
|
||||||
/* Combination of bits from enum UVERBS_ATTR_SPEC_F_XXXX */
|
|
||||||
u8 flags;
|
|
||||||
/*
|
/*
|
||||||
* higher bits mean the namespace and lower bits mean
|
* higher bits mean the namespace and lower bits mean
|
||||||
* the type id within the namespace.
|
* the type id within the namespace.
|
||||||
*/
|
*/
|
||||||
u16 obj_type;
|
u16 obj_type;
|
||||||
u8 access;
|
u8 access;
|
||||||
} obj;
|
} obj;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
u8 num_elems;
|
||||||
|
} enum_def;
|
||||||
|
} u;
|
||||||
|
|
||||||
|
/* This weird split of the enum lets us remove some padding */
|
||||||
|
union {
|
||||||
struct {
|
struct {
|
||||||
enum uverbs_attr_type type;
|
|
||||||
/* Combination of bits from enum UVERBS_ATTR_SPEC_F_XXXX */
|
|
||||||
u8 flags;
|
|
||||||
u8 num_elems;
|
|
||||||
/*
|
/*
|
||||||
* The enum attribute can select one of the attributes
|
* The enum attribute can select one of the attributes
|
||||||
* contained in the ids array. Currently only PTR_IN
|
* contained in the ids array. Currently only PTR_IN
|
||||||
* attributes are supported in the ids array.
|
* attributes are supported in the ids array.
|
||||||
*/
|
*/
|
||||||
const struct uverbs_attr_spec *ids;
|
const struct uverbs_attr_spec *ids;
|
||||||
} enum_def;
|
} enum_def;
|
||||||
};
|
} u2;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct uverbs_attr_spec_hash {
|
struct uverbs_attr_spec_hash {
|
||||||
|
@ -196,92 +192,72 @@ struct uverbs_object_tree_def {
|
||||||
const struct uverbs_object_def * const (*objects)[];
|
const struct uverbs_object_def * const (*objects)[];
|
||||||
};
|
};
|
||||||
|
|
||||||
#define UA_FLAGS(_flags) .flags = _flags
|
/*
|
||||||
#define __UVERBS_ATTR0(_id, _type, _fld, _attr, ...) \
|
* =======================================
|
||||||
((const struct uverbs_attr_def) \
|
* Attribute Specifications
|
||||||
{.id = _id, .attr = {{._fld = {.type = _type, _attr, .flags = 0, } }, } })
|
* =======================================
|
||||||
#define __UVERBS_ATTR1(_id, _type, _fld, _attr, _extra1, ...) \
|
*/
|
||||||
((const struct uverbs_attr_def) \
|
|
||||||
{.id = _id, .attr = {{._fld = {.type = _type, _attr, _extra1 } },} })
|
|
||||||
#define __UVERBS_ATTR2(_id, _type, _fld, _attr, _extra1, _extra2) \
|
|
||||||
((const struct uverbs_attr_def) \
|
|
||||||
{.id = _id, .attr = {{._fld = {.type = _type, _attr, _extra1, _extra2 } },} })
|
|
||||||
#define __UVERBS_ATTR(_id, _type, _fld, _attr, _extra1, _extra2, _n, ...) \
|
|
||||||
__UVERBS_ATTR##_n(_id, _type, _fld, _attr, _extra1, _extra2)
|
|
||||||
|
|
||||||
|
/* Use in the _type parameter for attribute specifications */
|
||||||
#define UVERBS_ATTR_TYPE(_type) \
|
#define UVERBS_ATTR_TYPE(_type) \
|
||||||
.min_len = sizeof(_type), .len = sizeof(_type)
|
.u.ptr.min_len = sizeof(_type), .u.ptr.len = sizeof(_type)
|
||||||
#define UVERBS_ATTR_STRUCT(_type, _last) \
|
#define UVERBS_ATTR_STRUCT(_type, _last) \
|
||||||
.min_len = ((uintptr_t)(&((_type *)0)->_last + 1)), .len = sizeof(_type)
|
.u.ptr.min_len = ((uintptr_t)(&((_type *)0)->_last + 1)), .u.ptr.len = sizeof(_type)
|
||||||
#define UVERBS_ATTR_SIZE(_min_len, _len) \
|
#define UVERBS_ATTR_SIZE(_min_len, _len) \
|
||||||
.min_len = _min_len, .len = _len
|
.u.ptr.min_len = _min_len, .u.ptr.len = _len
|
||||||
#define UVERBS_ATTR_MIN_SIZE(_min_len) \
|
#define UVERBS_ATTR_MIN_SIZE(_min_len) \
|
||||||
UVERBS_ATTR_SIZE(_min_len, USHRT_MAX)
|
UVERBS_ATTR_SIZE(_min_len, USHRT_MAX)
|
||||||
|
|
||||||
/*
|
/* Must be used in the '...' of any UVERBS_ATTR */
|
||||||
* In new compiler, UVERBS_ATTR could be simplified by declaring it as
|
#define UA_FLAGS(_flags) .flags = _flags
|
||||||
* [_id] = {.type = _type, .len = _len, ##__VA_ARGS__}
|
|
||||||
* But since we support older compilers too, we need the more complex code.
|
#define UVERBS_ATTR_IDR(_attr_id, _idr_type, _access, ...) \
|
||||||
*/
|
((const struct uverbs_attr_def){ \
|
||||||
#define UVERBS_ATTR(_id, _type, _fld, _attr, ...) \
|
.id = _attr_id, \
|
||||||
__UVERBS_ATTR(_id, _type, _fld, _attr, ##__VA_ARGS__, 2, 1, 0)
|
.attr = { .type = UVERBS_ATTR_TYPE_IDR, \
|
||||||
#define UVERBS_ATTR_PTR_IN_SZ(_id, _len, ...) \
|
.u.obj.obj_type = _idr_type, \
|
||||||
UVERBS_ATTR(_id, UVERBS_ATTR_TYPE_PTR_IN, ptr, _len, ##__VA_ARGS__)
|
.u.obj.access = _access, \
|
||||||
/* If sizeof(_type) <= sizeof(u64), this will be inlined rather than a pointer */
|
__VA_ARGS__ } })
|
||||||
#define UVERBS_ATTR_PTR_IN(_id, _type, ...) \
|
|
||||||
UVERBS_ATTR_PTR_IN_SZ(_id, _type, ##__VA_ARGS__)
|
#define UVERBS_ATTR_FD(_attr_id, _fd_type, _access, ...) \
|
||||||
#define UVERBS_ATTR_PTR_OUT_SZ(_id, _len, ...) \
|
((const struct uverbs_attr_def){ \
|
||||||
UVERBS_ATTR(_id, UVERBS_ATTR_TYPE_PTR_OUT, ptr, _len, ##__VA_ARGS__)
|
.id = (_attr_id) + \
|
||||||
#define UVERBS_ATTR_PTR_OUT(_id, _type, ...) \
|
BUILD_BUG_ON_ZERO((_access) != UVERBS_ACCESS_NEW && \
|
||||||
UVERBS_ATTR_PTR_OUT_SZ(_id, _type, ##__VA_ARGS__)
|
(_access) != UVERBS_ACCESS_READ), \
|
||||||
#define UVERBS_ATTR_ENUM_IN(_id, _enum_arr, ...) \
|
.attr = { .type = UVERBS_ATTR_TYPE_FD, \
|
||||||
UVERBS_ATTR(_id, UVERBS_ATTR_TYPE_ENUM_IN, enum_def, \
|
.u.obj.obj_type = _fd_type, \
|
||||||
.ids = (_enum_arr), \
|
.u.obj.access = _access, \
|
||||||
.num_elems = ARRAY_SIZE(_enum_arr), ##__VA_ARGS__)
|
__VA_ARGS__ } })
|
||||||
|
|
||||||
|
#define UVERBS_ATTR_PTR_IN(_attr_id, _type, ...) \
|
||||||
|
((const struct uverbs_attr_def){ \
|
||||||
|
.id = _attr_id, \
|
||||||
|
.attr = { .type = UVERBS_ATTR_TYPE_PTR_IN, \
|
||||||
|
_type, \
|
||||||
|
__VA_ARGS__ } })
|
||||||
|
|
||||||
|
#define UVERBS_ATTR_PTR_OUT(_attr_id, _type, ...) \
|
||||||
|
((const struct uverbs_attr_def){ \
|
||||||
|
.id = _attr_id, \
|
||||||
|
.attr = { .type = UVERBS_ATTR_TYPE_PTR_OUT, \
|
||||||
|
_type, \
|
||||||
|
__VA_ARGS__ } })
|
||||||
|
|
||||||
|
/* _enum_arry should be a 'static const union uverbs_attr_spec[]' */
|
||||||
|
#define UVERBS_ATTR_ENUM_IN(_attr_id, _enum_arr, ...) \
|
||||||
|
((const struct uverbs_attr_def){ \
|
||||||
|
.id = _attr_id, \
|
||||||
|
.attr = { .type = UVERBS_ATTR_TYPE_ENUM_IN, \
|
||||||
|
.u2.enum_def.ids = _enum_arr, \
|
||||||
|
.u.enum_def.num_elems = ARRAY_SIZE(_enum_arr), \
|
||||||
|
__VA_ARGS__ }, \
|
||||||
|
})
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* In new compiler, UVERBS_ATTR_IDR (and FD) could be simplified by declaring
|
* =======================================
|
||||||
* it as
|
* Declaration helpers
|
||||||
* {.id = _id, \
|
* =======================================
|
||||||
* .attr {.type = __obj_class, \
|
|
||||||
* .obj = {.obj_type = _idr_type, \
|
|
||||||
* .access = _access \
|
|
||||||
* }, ##__VA_ARGS__ } }
|
|
||||||
* But since we support older compilers too, we need the more complex code.
|
|
||||||
*/
|
*/
|
||||||
#define ___UVERBS_ATTR_OBJ0(_id, _obj_class, _obj_type, _access, ...)\
|
|
||||||
((const struct uverbs_attr_def) \
|
|
||||||
{.id = _id, \
|
|
||||||
.attr = { {.obj = {.type = _obj_class, .obj_type = _obj_type, \
|
|
||||||
.access = _access, .flags = 0 } }, } })
|
|
||||||
#define ___UVERBS_ATTR_OBJ1(_id, _obj_class, _obj_type, _access, _flags)\
|
|
||||||
((const struct uverbs_attr_def) \
|
|
||||||
{.id = _id, \
|
|
||||||
.attr = { {.obj = {.type = _obj_class, .obj_type = _obj_type, \
|
|
||||||
.access = _access, _flags} }, } })
|
|
||||||
#define ___UVERBS_ATTR_OBJ(_id, _obj_class, _obj_type, _access, _flags, \
|
|
||||||
_n, ...) \
|
|
||||||
___UVERBS_ATTR_OBJ##_n(_id, _obj_class, _obj_type, _access, _flags)
|
|
||||||
#define __UVERBS_ATTR_OBJ(_id, _obj_class, _obj_type, _access, ...) \
|
|
||||||
___UVERBS_ATTR_OBJ(_id, _obj_class, _obj_type, _access, \
|
|
||||||
##__VA_ARGS__, 1, 0)
|
|
||||||
#define UVERBS_ATTR_IDR(_id, _idr_type, _access, ...) \
|
|
||||||
__UVERBS_ATTR_OBJ(_id, UVERBS_ATTR_TYPE_IDR, _idr_type, _access,\
|
|
||||||
##__VA_ARGS__)
|
|
||||||
#define UVERBS_ATTR_FD(_id, _fd_type, _access, ...) \
|
|
||||||
__UVERBS_ATTR_OBJ(_id, UVERBS_ATTR_TYPE_FD, _fd_type, \
|
|
||||||
(_access) + BUILD_BUG_ON_ZERO( \
|
|
||||||
(_access) != UVERBS_ACCESS_NEW && \
|
|
||||||
(_access) != UVERBS_ACCESS_READ), \
|
|
||||||
##__VA_ARGS__)
|
|
||||||
#define DECLARE_UVERBS_ATTR_SPEC(_name, ...) \
|
|
||||||
const struct uverbs_attr_def _name = __VA_ARGS__
|
|
||||||
|
|
||||||
#define DECLARE_UVERBS_ENUM(_name, ...) \
|
|
||||||
const struct uverbs_enum_spec _name = { \
|
|
||||||
.len = ARRAY_SIZE(((struct uverbs_attr_spec[]){__VA_ARGS__})),\
|
|
||||||
.ids = {__VA_ARGS__}, \
|
|
||||||
}
|
|
||||||
#define _UVERBS_METHOD_ATTRS_SZ(...) \
|
#define _UVERBS_METHOD_ATTRS_SZ(...) \
|
||||||
(sizeof((const struct uverbs_attr_def * const []){__VA_ARGS__}) /\
|
(sizeof((const struct uverbs_attr_def * const []){__VA_ARGS__}) /\
|
||||||
sizeof(const struct uverbs_attr_def *))
|
sizeof(const struct uverbs_attr_def *))
|
||||||
|
|
Loading…
Reference in New Issue