@@ -191,7 +191,10 @@ struct ib_ucq_object {
u32 async_events_reported;
};
+struct uverbs_type_group;
+
extern const struct file_operations uverbs_event_fops;
+void uverbs_initialize_type_group(const struct uverbs_type_group *type_group);
void ib_uverbs_init_event_queue(struct ib_uverbs_event_queue *ev_queue);
struct file *ib_uverbs_alloc_async_event_file(struct ib_uverbs_file *uverbs_file,
struct ib_device *ib_dev);
@@ -349,3 +349,61 @@ long ib_uverbs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
return err;
}
+
+static void uverbs_initialize_action(struct uverbs_action *action)
+{
+ size_t attr_group_idx;
+
+ for (attr_group_idx = 0; attr_group_idx < action->num_groups;
+ attr_group_idx++) {
+ struct uverbs_attr_spec_group *attr_group =
+ action->attr_groups[attr_group_idx];
+ size_t attr_idx;
+
+ if (!attr_group)
+ continue;
+ action->num_child_attrs += attr_group->num_attrs;
+ for (attr_idx = 0; attr_idx < attr_group->num_attrs;
+ attr_idx++) {
+ struct uverbs_attr_spec *attr =
+ &attr_group->attrs[attr_idx];
+
+ if (attr->flags & UVERBS_ATTR_SPEC_F_MANDATORY)
+ set_bit(attr_idx,
+ attr_group->mandatory_attrs_bitmask);
+ }
+ }
+}
+
+void uverbs_initialize_type_group(const struct uverbs_type_group *type_group)
+{
+ size_t type_idx;
+
+ for (type_idx = 0; type_idx < type_group->num_types; type_idx++) {
+ const struct uverbs_type *type = type_group->types[type_idx];
+ size_t action_group_idx;
+
+ if (!type)
+ continue;
+ for (action_group_idx = 0;
+ action_group_idx < type->num_groups;
+ action_group_idx++) {
+ const struct uverbs_action_group *action_group =
+ type->action_groups[action_group_idx];
+ size_t action_idx;
+
+ if (!action_group)
+ continue;
+ for (action_idx = 0;
+ action_idx < action_group->num_actions;
+ action_idx++) {
+ struct uverbs_action *action =
+ action_group->actions[action_idx];
+
+ if (!action)
+ continue;
+ uverbs_initialize_action(action);
+ }
+ }
+ }
+}
@@ -45,6 +45,7 @@
#include <linux/cdev.h>
#include <linux/anon_inodes.h>
#include <linux/slab.h>
+#include <rdma/uverbs_std_types.h>
#include <linux/uaccess.h>
@@ -1253,6 +1254,8 @@ static int __init ib_uverbs_init(void)
{
int ret;
+ uverbs_initialize_type_group(&uverbs_common_types);
+
ret = register_chrdev_region(IB_UVERBS_BASE_DEV, IB_UVERBS_MAX_DEVICES,
"infiniband_verbs");
if (ret) {
In order to accelerate the validation and parsing process, we calculate the number of attributes of all groups in an action and the mandatory attributes bitmask in advance. Signed-off-by: Matan Barak <matanb@mellanox.com> --- drivers/infiniband/core/uverbs.h | 3 ++ drivers/infiniband/core/uverbs_ioctl.c | 58 ++++++++++++++++++++++++++++++++++ drivers/infiniband/core/uverbs_main.c | 3 ++ 3 files changed, 64 insertions(+)