IB/core: Assign root to all drivers
authorMatan Barak <matanb@mellanox.com>
Thu, 3 Aug 2017 13:07:06 +0000 (16:07 +0300)
committerDoug Ledford <dledford@redhat.com>
Thu, 31 Aug 2017 12:35:14 +0000 (08:35 -0400)
In order to use the parsing tree, we need to assign the root
to all drivers. Currently, we just assign the default parsing
tree via ib_uverbs_add_one. The driver could override this by
assigning a parsing tree prior to registering the device.

Signed-off-by: Matan Barak <matanb@mellanox.com>
Reviewed-by: Yishai Hadas <yishaih@mellanox.com>
Signed-off-by: Doug Ledford <dledford@redhat.com>
drivers/infiniband/core/uverbs.h
drivers/infiniband/core/uverbs_main.c
include/rdma/uverbs_ioctl.h
include/rdma/uverbs_std_types.h

index 64d494a64daf37011b7dad03574dde71343d57d7..0f6f768f687eebf56888f3df51de2e8e54f1af85 100644 (file)
@@ -100,6 +100,7 @@ struct ib_uverbs_device {
        struct mutex                            lists_mutex; /* protect lists */
        struct list_head                        uverbs_file_list;
        struct list_head                        uverbs_events_file_list;
+       struct uverbs_root_spec                 *specs_root;
 };
 
 struct ib_uverbs_event_queue {
index defeda33e27f828d74627e7241be4feb63b9b134..872fec910c161942f0ec6a4c7bb6ad17d9393f2f 100644 (file)
@@ -49,6 +49,7 @@
 #include <linux/uaccess.h>
 
 #include <rdma/ib.h>
+#include <rdma/uverbs_std_types.h>
 
 #include "uverbs.h"
 #include "core_priv.h"
@@ -1097,6 +1098,18 @@ static void ib_uverbs_add_one(struct ib_device *device)
        if (device_create_file(uverbs_dev->dev, &dev_attr_abi_version))
                goto err_class;
 
+       if (!device->specs_root) {
+               const struct uverbs_object_tree_def *default_root[] = {
+                       uverbs_default_get_objects()};
+
+               uverbs_dev->specs_root = uverbs_alloc_spec_tree(1,
+                                                               default_root);
+               if (IS_ERR(uverbs_dev->specs_root))
+                       goto err_class;
+
+               device->specs_root = uverbs_dev->specs_root;
+       }
+
        ib_set_client_data(device, &uverbs_client, uverbs_dev);
 
        return;
@@ -1228,6 +1241,11 @@ static void ib_uverbs_remove_one(struct ib_device *device, void *client_data)
                ib_uverbs_comp_dev(uverbs_dev);
        if (wait_clients)
                wait_for_completion(&uverbs_dev->comp);
+       if (uverbs_dev->specs_root) {
+               uverbs_free_spec_tree(uverbs_dev->specs_root);
+               device->specs_root = NULL;
+       }
+
        kobject_put(&uverbs_dev->kobj);
 }
 
index 759afa0621ea38f3f4c36b1ab3342eb9ce96a15a..6da44079aa58961cccde88f8366944f2c96166c0 100644 (file)
@@ -419,8 +419,20 @@ static inline int _uverbs_copy_from(void *to, size_t to_size,
  * An object without any methods is considered invalid and will abort the
  * function with -ENOENT error.
  */
+#if IS_ENABLED(CONFIG_INFINIBAND_USER_ACCESS)
 struct uverbs_root_spec *uverbs_alloc_spec_tree(unsigned int num_trees,
                                                const struct uverbs_object_tree_def **trees);
 void uverbs_free_spec_tree(struct uverbs_root_spec *root);
+#else
+static inline struct uverbs_root_spec *uverbs_alloc_spec_tree(unsigned int num_trees,
+                                                             const struct uverbs_object_tree_def **trees)
+{
+       return NULL;
+}
+
+static inline void uverbs_free_spec_tree(struct uverbs_root_spec *root)
+{
+}
+#endif
 
 #endif
index 400efe2a4d3cfcb0fc2d323af1a5b8dc1dae6648..5f8e20bbd67ceb06a5d51e94de3c17c557c9559a 100644 (file)
 #define _UVERBS_STD_TYPES__
 
 #include <rdma/uverbs_types.h>
+#include <rdma/uverbs_ioctl.h>
 #include <rdma/ib_user_ioctl_verbs.h>
 
+#if IS_ENABLED(CONFIG_INFINIBAND_USER_ACCESS)
 extern const struct uverbs_object_def uverbs_object_comp_channel;
 extern const struct uverbs_object_def uverbs_object_cq;
 extern const struct uverbs_object_def uverbs_object_qp;
@@ -50,6 +52,18 @@ extern const struct uverbs_object_def uverbs_object_pd;
 extern const struct uverbs_object_def uverbs_object_xrcd;
 extern const struct uverbs_object_def uverbs_object_device;
 
+extern const struct uverbs_object_tree_def uverbs_default_objects;
+static inline const struct uverbs_object_tree_def *uverbs_default_get_objects(void)
+{
+       return &uverbs_default_objects;
+}
+#else
+static inline const struct uverbs_object_tree_def *uverbs_default_get_objects(void)
+{
+       return NULL;
+}
+#endif
+
 static inline struct ib_uobject *__uobj_get(const struct uverbs_obj_type *type,
                                            bool write,
                                            struct ib_ucontext *ucontext,