[PATCH RFC 06/10] IB/core: Initialize uverbs types specification

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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@xxxxxxxxxxxx>
---
 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(+)

diff --git a/drivers/infiniband/core/uverbs.h b/drivers/infiniband/core/uverbs.h
index a3230b6..6e59a00 100644
--- a/drivers/infiniband/core/uverbs.h
+++ b/drivers/infiniband/core/uverbs.h
@@ -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);
diff --git a/drivers/infiniband/core/uverbs_ioctl.c b/drivers/infiniband/core/uverbs_ioctl.c
index 3465a18..18c0799 100644
--- a/drivers/infiniband/core/uverbs_ioctl.c
+++ b/drivers/infiniband/core/uverbs_ioctl.c
@@ -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);
+			}
+		}
+	}
+}
diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c
index b282daf..44c4d92 100644
--- a/drivers/infiniband/core/uverbs_main.c
+++ b/drivers/infiniband/core/uverbs_main.c
@@ -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) {
-- 
1.8.3.1

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Photo]     [Yosemite News]     [Yosemite Photos]     [Linux Kernel]     [Linux SCSI]     [XFree86]
  Powered by Linux