RDMA/uverbs: Simplify UVERBS_ATTR family of macros
authorJason Gunthorpe <jgg@mellanox.com>
Wed, 4 Jul 2018 05:50:25 +0000 (08:50 +0300)
committerJason Gunthorpe <jgg@mellanox.com>
Wed, 4 Jul 2018 19:47:01 +0000 (13:47 -0600)
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>
drivers/infiniband/core/uverbs_ioctl.c
drivers/infiniband/core/uverbs_ioctl_merge.c
drivers/infiniband/core/uverbs_std_types.c
drivers/infiniband/core/uverbs_std_types_flow_action.c
drivers/infiniband/hw/mlx5/devx.c
include/rdma/uverbs_ioctl.h

index 785975a..62f7382 100644 (file)
@@ -77,13 +77,13 @@ static int uverbs_process_attr(struct ib_uverbs_file *ufile,
 
        switch (spec->type) {
        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;
 
                if (uattr->attr_data.enum_data.reserved)
                        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 */
                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
                 * 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 &&
-                   !uverbs_is_attr_cleared(uattr, val_spec->ptr.len))
+                   !uverbs_is_attr_cleared(uattr, val_spec->u.ptr.len))
                        return -EOPNOTSUPP;
 
        /* fall through */
        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) &&
-                    uattr->len > val_spec->ptr.len))
+                    uattr->len > val_spec->u.ptr.len))
                        return -EINVAL;
 
                if (spec->type != UVERBS_ATTR_TYPE_ENUM_IN &&
@@ -149,20 +149,20 @@ static int uverbs_process_attr(struct ib_uverbs_file *ufile,
                        return -EINVAL;
 
                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)
                        return -EINVAL;
 
                o_attr->uobject = uverbs_get_uobject_from_context(
                                        object->type_attrs,
                                        ufile->ucontext,
-                                       spec->obj.access,
+                                       spec->u.obj.access,
                                        (int)uattr->data);
 
                if (IS_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;
 
                        /* 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(
                                        attr->obj_attr.uobject,
-                                       spec->obj.access, commit);
+                                       spec->u.obj.access, commit);
                                if (!ret)
                                        ret = current_ret;
                        } else if (spec->type == UVERBS_ATTR_TYPE_PTR_IN &&
index 6ceb672..cdada52 100644 (file)
@@ -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));
 
                        attr_obj_with_special_access = IS_ATTR_OBJECT(attr) &&
-                                  (attr->obj.access == UVERBS_ACCESS_NEW ||
-                                   attr->obj.access == UVERBS_ACCESS_DESTROY);
+                                  (attr->u.obj.access == UVERBS_ACCESS_NEW ||
+                                   attr->u.obj.access == UVERBS_ACCESS_DESTROY);
                        num_of_singularities +=  !!attr_obj_with_special_access;
                        if (WARN(num_of_singularities > 1,
                                 "ib_uverbs: Method contains more than one object attr (%d) with new/destroy access\n",
index c7f93b2..ed63eed 100644 (file)
@@ -222,11 +222,11 @@ int uverbs_destroy_def_handler(struct ib_device *ib_dev,
  * spec.
  */
 const struct uverbs_attr_def uverbs_uhw_compat_in =
-       UVERBS_ATTR_PTR_IN_SZ(UVERBS_ATTR_UHW_IN, UVERBS_ATTR_MIN_SIZE(0),
-                             UA_FLAGS(UVERBS_ATTR_SPEC_F_MIN_SZ_OR_ZERO));
+       UVERBS_ATTR_PTR_IN(UVERBS_ATTR_UHW_IN, UVERBS_ATTR_MIN_SIZE(0),
+                          UA_FLAGS(UVERBS_ATTR_SPEC_F_MIN_SZ_OR_ZERO));
 const struct uverbs_attr_def uverbs_uhw_compat_out =
-       UVERBS_ATTR_PTR_OUT_SZ(UVERBS_ATTR_UHW_OUT, UVERBS_ATTR_MIN_SIZE(0),
-                              UA_FLAGS(UVERBS_ATTR_SPEC_F_MIN_SZ_OR_ZERO));
+       UVERBS_ATTR_PTR_OUT(UVERBS_ATTR_UHW_OUT, UVERBS_ATTR_MIN_SIZE(0),
+                           UA_FLAGS(UVERBS_ATTR_SPEC_F_MIN_SZ_OR_ZERO));
 
 void create_udata(struct uverbs_attr_bundle *ctx, struct ib_udata *udata)
 {
index afbb190..1ba55d4 100644 (file)
@@ -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[] = {
        [IB_UVERBS_FLOW_ACTION_ESP_KEYMAT_AES_GCM] = {
-               { .ptr = {
-                       .type = UVERBS_ATTR_TYPE_PTR_IN,
-                       UVERBS_ATTR_TYPE(struct ib_uverbs_flow_action_esp_keymat_aes_gcm),
-                       .flags = UVERBS_ATTR_SPEC_F_MIN_SZ_OR_ZERO,
-               } },
+               .type = UVERBS_ATTR_TYPE_PTR_IN,
+               UVERBS_ATTR_TYPE(struct ib_uverbs_flow_action_esp_keymat_aes_gcm),
+               UA_FLAGS(UVERBS_ATTR_SPEC_F_MIN_SZ_OR_ZERO),
        },
 };
 
 static const struct uverbs_attr_spec uverbs_flow_action_esp_replay[] = {
        [IB_UVERBS_FLOW_ACTION_ESP_REPLAY_NONE] = {
-               { .ptr = {
-                       .type = UVERBS_ATTR_TYPE_PTR_IN,
-                       /* No need to specify any data */
-                       .len = 0,
-               } }
+               .type = UVERBS_ATTR_TYPE_PTR_IN,
+               /* No need to specify any data */
+               UVERBS_ATTR_SIZE(0, 0),
        },
        [IB_UVERBS_FLOW_ACTION_ESP_REPLAY_BMP] = {
-               { .ptr = {
-                       .type = UVERBS_ATTR_TYPE_PTR_IN,
-                       UVERBS_ATTR_STRUCT(struct ib_uverbs_flow_action_esp_replay_bmp, size),
-                       .flags = UVERBS_ATTR_SPEC_F_MIN_SZ_OR_ZERO,
-               } }
+               .type = UVERBS_ATTR_TYPE_PTR_IN,
+               UVERBS_ATTR_STRUCT(struct ib_uverbs_flow_action_esp_replay_bmp, size),
+               UA_FLAGS(UVERBS_ATTR_SPEC_F_MIN_SZ_OR_ZERO),
        },
 };
 
index 30f6b61..2f75edc 100644 (file)
@@ -1017,15 +1017,15 @@ static DECLARE_UVERBS_NAMED_METHOD(MLX5_IB_METHOD_DEVX_QUERY_UAR,
                             UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY)));
 
 static DECLARE_UVERBS_NAMED_METHOD(MLX5_IB_METHOD_DEVX_OTHER,
-       &UVERBS_ATTR_PTR_IN_SZ(MLX5_IB_ATTR_DEVX_OTHER_CMD_IN,
-                              UVERBS_ATTR_MIN_SIZE(MLX5_ST_SZ_BYTES(general_obj_in_cmd_hdr)),
-                              UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY |
-                                       UVERBS_ATTR_SPEC_F_MIN_SZ_OR_ZERO |
-                                       UVERBS_ATTR_SPEC_F_ALLOC_AND_COPY)),
-       &UVERBS_ATTR_PTR_OUT_SZ(MLX5_IB_ATTR_DEVX_OTHER_CMD_OUT,
-                               UVERBS_ATTR_MIN_SIZE(MLX5_ST_SZ_BYTES(general_obj_out_cmd_hdr)),
-                               UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY |
-                                        UVERBS_ATTR_SPEC_F_MIN_SZ_OR_ZERO))
+       &UVERBS_ATTR_PTR_IN(MLX5_IB_ATTR_DEVX_OTHER_CMD_IN,
+                           UVERBS_ATTR_MIN_SIZE(MLX5_ST_SZ_BYTES(general_obj_in_cmd_hdr)),
+                           UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY |
+                                    UVERBS_ATTR_SPEC_F_MIN_SZ_OR_ZERO |
+                                    UVERBS_ATTR_SPEC_F_ALLOC_AND_COPY)),
+       &UVERBS_ATTR_PTR_OUT(MLX5_IB_ATTR_DEVX_OTHER_CMD_OUT,
+                            UVERBS_ATTR_MIN_SIZE(MLX5_ST_SZ_BYTES(general_obj_out_cmd_hdr)),
+                            UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY |
+                                     UVERBS_ATTR_SPEC_F_MIN_SZ_OR_ZERO))
 );
 
 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,
                         UVERBS_ACCESS_NEW,
                         UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY)),
-       &UVERBS_ATTR_PTR_IN_SZ(MLX5_IB_ATTR_DEVX_OBJ_CREATE_CMD_IN,
-                              UVERBS_ATTR_MIN_SIZE(MLX5_ST_SZ_BYTES(general_obj_in_cmd_hdr)),
-                              UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY |
-                                       UVERBS_ATTR_SPEC_F_MIN_SZ_OR_ZERO |
-                                       UVERBS_ATTR_SPEC_F_ALLOC_AND_COPY)),
-       &UVERBS_ATTR_PTR_OUT_SZ(MLX5_IB_ATTR_DEVX_OBJ_CREATE_CMD_OUT,
-                               UVERBS_ATTR_MIN_SIZE(MLX5_ST_SZ_BYTES(general_obj_out_cmd_hdr)),
-                               UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY |
-                                        UVERBS_ATTR_SPEC_F_MIN_SZ_OR_ZERO)));
+       &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)),
+                           UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY |
+                                    UVERBS_ATTR_SPEC_F_MIN_SZ_OR_ZERO |
+                                    UVERBS_ATTR_SPEC_F_ALLOC_AND_COPY)),
+       &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)),
+                            UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY |
+                                     UVERBS_ATTR_SPEC_F_MIN_SZ_OR_ZERO)));
 
 static DECLARE_UVERBS_NAMED_METHOD(MLX5_IB_METHOD_DEVX_OBJ_DESTROY,
        &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,
                         UVERBS_ACCESS_WRITE,
                         UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY)),
-       &UVERBS_ATTR_PTR_IN_SZ(MLX5_IB_ATTR_DEVX_OBJ_MODIFY_CMD_IN,
-                              UVERBS_ATTR_MIN_SIZE(MLX5_ST_SZ_BYTES(general_obj_in_cmd_hdr)),
-                              UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY |
-                                       UVERBS_ATTR_SPEC_F_MIN_SZ_OR_ZERO |
-                                       UVERBS_ATTR_SPEC_F_ALLOC_AND_COPY)),
-       &UVERBS_ATTR_PTR_OUT_SZ(MLX5_IB_ATTR_DEVX_OBJ_MODIFY_CMD_OUT,
-                               UVERBS_ATTR_MIN_SIZE(MLX5_ST_SZ_BYTES(general_obj_out_cmd_hdr)),
-                               UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY |
-                                        UVERBS_ATTR_SPEC_F_MIN_SZ_OR_ZERO)));
+       &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)),
+                           UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY |
+                                    UVERBS_ATTR_SPEC_F_MIN_SZ_OR_ZERO |
+                                    UVERBS_ATTR_SPEC_F_ALLOC_AND_COPY)),
+       &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)),
+                            UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY |
+                                     UVERBS_ATTR_SPEC_F_MIN_SZ_OR_ZERO)));
 
 static DECLARE_UVERBS_NAMED_METHOD(MLX5_IB_METHOD_DEVX_OBJ_QUERY,
        &UVERBS_ATTR_IDR(MLX5_IB_ATTR_DEVX_OBJ_QUERY_HANDLE,
                         MLX5_IB_OBJECT_DEVX_OBJ,
                         UVERBS_ACCESS_READ,
                         UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY)),
-       &UVERBS_ATTR_PTR_IN_SZ(MLX5_IB_ATTR_DEVX_OBJ_QUERY_CMD_IN,
-                              UVERBS_ATTR_MIN_SIZE(MLX5_ST_SZ_BYTES(general_obj_in_cmd_hdr)),
-                              UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY |
-                                       UVERBS_ATTR_SPEC_F_MIN_SZ_OR_ZERO |
-                                       UVERBS_ATTR_SPEC_F_ALLOC_AND_COPY)),
-       &UVERBS_ATTR_PTR_OUT_SZ(MLX5_IB_ATTR_DEVX_OBJ_QUERY_CMD_OUT,
-                               UVERBS_ATTR_MIN_SIZE(MLX5_ST_SZ_BYTES(general_obj_out_cmd_hdr)),
-                               UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY |
-                                        UVERBS_ATTR_SPEC_F_MIN_SZ_OR_ZERO)));
+       &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)),
+                           UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY |
+                                    UVERBS_ATTR_SPEC_F_MIN_SZ_OR_ZERO |
+                                    UVERBS_ATTR_SPEC_F_ALLOC_AND_COPY)),
+       &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)),
+                            UA_FLAGS(UVERBS_ATTR_SPEC_F_MANDATORY |
+                                     UVERBS_ATTR_SPEC_F_MIN_SZ_OR_ZERO)));
 
 static DECLARE_UVERBS_GLOBAL_METHODS(MLX5_IB_OBJECT_DEVX,
        &UVERBS_METHOD(MLX5_IB_METHOD_DEVX_OTHER),
index 90a4947..a7246e9 100644 (file)
@@ -73,46 +73,42 @@ enum {
 
 /* Specification of a single attribute inside the ioctl message */
 struct uverbs_attr_spec {
+       u8 type;
+       u8 flags;
+
        union {
-               /* Header shared by all following union members - to reduce space. */
-               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 */
-                       u16                             len;
+                       u16 len;
                        /* User isn't allowed to provide something < min_len */
-                       u16                             min_len;
+                       u16 min_len;
                } ptr;
+
                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
                         * the type id within the namespace.
                         */
-                       u16                     obj_type;
-                       u8                      access;
+                       u16 obj_type;
+                       u8 access;
                } obj;
+
+               struct {
+                       u8 num_elems;
+               } enum_def;
+       } u;
+
+       /* This weird split of the enum lets us remove some padding */
+       union {
                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
                         * contained in the ids array. Currently only PTR_IN
                         * attributes are supported in the ids array.
                         */
-                       const struct uverbs_attr_spec   *ids;
+                       const struct uverbs_attr_spec *ids;
                } enum_def;
-       };
+       } u2;
 };
 
 struct uverbs_attr_spec_hash {
@@ -196,92 +192,72 @@ struct uverbs_object_tree_def {
        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)                           \
-        {.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)
+/*
+ * =======================================
+ *     Attribute Specifications
+ * =======================================
+ */
 
+/* Use in the _type parameter for attribute specifications */
 #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)                       \
-       .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)                       \
-       .min_len = _min_len, .len = _len
+       .u.ptr.min_len = _min_len, .u.ptr.len = _len
 #define UVERBS_ATTR_MIN_SIZE(_min_len)                         \
        UVERBS_ATTR_SIZE(_min_len, USHRT_MAX)
 
-/*
- * In new compiler, UVERBS_ATTR could be simplified by declaring it as
- * [_id] = {.type = _type, .len = _len, ##__VA_ARGS__}
- * But since we support older compilers too, we need the more complex code.
- */
-#define UVERBS_ATTR(_id, _type, _fld, _attr, ...)                      \
-       __UVERBS_ATTR(_id, _type, _fld, _attr, ##__VA_ARGS__, 2, 1, 0)
-#define UVERBS_ATTR_PTR_IN_SZ(_id, _len, ...)                          \
-       UVERBS_ATTR(_id, UVERBS_ATTR_TYPE_PTR_IN, ptr, _len, ##__VA_ARGS__)
-/* If sizeof(_type) <= sizeof(u64), this will be inlined rather than a pointer */
-#define UVERBS_ATTR_PTR_IN(_id, _type, ...)                            \
-       UVERBS_ATTR_PTR_IN_SZ(_id, _type, ##__VA_ARGS__)
-#define UVERBS_ATTR_PTR_OUT_SZ(_id, _len, ...)                         \
-       UVERBS_ATTR(_id, UVERBS_ATTR_TYPE_PTR_OUT, ptr, _len, ##__VA_ARGS__)
-#define UVERBS_ATTR_PTR_OUT(_id, _type, ...)                           \
-       UVERBS_ATTR_PTR_OUT_SZ(_id, _type, ##__VA_ARGS__)
-#define UVERBS_ATTR_ENUM_IN(_id, _enum_arr, ...)                       \
-       UVERBS_ATTR(_id, UVERBS_ATTR_TYPE_ENUM_IN, enum_def,            \
-                   .ids = (_enum_arr),                                 \
-                   .num_elems = ARRAY_SIZE(_enum_arr), ##__VA_ARGS__)
+/* Must be used in the '...' of any UVERBS_ATTR */
+#define UA_FLAGS(_flags) .flags = _flags
+
+#define UVERBS_ATTR_IDR(_attr_id, _idr_type, _access, ...)                     \
+       ((const struct uverbs_attr_def){                                       \
+               .id = _attr_id,                                                \
+               .attr = { .type = UVERBS_ATTR_TYPE_IDR,                        \
+                         .u.obj.obj_type = _idr_type,                         \
+                         .u.obj.access = _access,                             \
+                         __VA_ARGS__ } })
+
+#define UVERBS_ATTR_FD(_attr_id, _fd_type, _access, ...)                       \
+       ((const struct uverbs_attr_def){                                       \
+               .id = (_attr_id) +                                             \
+                     BUILD_BUG_ON_ZERO((_access) != UVERBS_ACCESS_NEW &&      \
+                                       (_access) != UVERBS_ACCESS_READ),      \
+               .attr = { .type = UVERBS_ATTR_TYPE_FD,                         \
+                         .u.obj.obj_type = _fd_type,                          \
+                         .u.obj.access = _access,                             \
+                         __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
- * {.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.
+ * =======================================
+ *     Declaration helpers
+ * =======================================
  */
-#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(...)                                   \
        (sizeof((const struct uverbs_attr_def * const []){__VA_ARGS__}) /\
         sizeof(const struct uverbs_attr_def *))