IB/uverbs: Have the core code create the uverbs_root_spec
authorJason Gunthorpe <jgg@mellanox.com>
Fri, 10 Aug 2018 02:14:35 +0000 (20:14 -0600)
committerJason Gunthorpe <jgg@mellanox.com>
Fri, 10 Aug 2018 22:06:24 +0000 (16:06 -0600)
There is no reason for drivers to do this, the core code should take of
everything. The drivers will provide their information from rodata to
describe their modifications to the core's base uapi specification.

The core uses this to build up the runtime uapi for each device.

Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
Reviewed-by: Michael J. Ruhl <michael.j.ruhl@intel.com>
Reviewed-by: Leon Romanovsky <leonro@mellanox.com>
drivers/infiniband/core/uverbs_ioctl_merge.c
drivers/infiniband/core/uverbs_main.c
drivers/infiniband/core/uverbs_std_types.c
drivers/infiniband/hw/mlx5/main.c
drivers/infiniband/hw/mlx5/mlx5_ib.h
include/rdma/ib_verbs.h

index f81aa888ce5c4c957bbd1ddb4c0e08b92989f0ce..16b5759299158177ca89f526915eeb42ffa50389 100644 (file)
@@ -556,7 +556,6 @@ void uverbs_free_spec_tree(struct uverbs_root_spec *root)
 
        kfree(root);
 }
-EXPORT_SYMBOL(uverbs_free_spec_tree);
 
 struct uverbs_root_spec *uverbs_alloc_spec_tree(unsigned int num_trees,
                                                const struct uverbs_object_tree_def **trees)
@@ -661,4 +660,3 @@ free_root:
        uverbs_free_spec_tree(root_spec);
        return ERR_PTR(res);
 }
-EXPORT_SYMBOL(uverbs_alloc_spec_tree);
index 6f62146e9738a06de3f54c694d15c4ef0618e1b3..20003594b5d6a7c627ebfe4afcee6301a9d0263d 100644 (file)
@@ -994,6 +994,36 @@ static DEVICE_ATTR(abi_version, S_IRUGO, show_dev_abi_version, NULL);
 static CLASS_ATTR_STRING(abi_version, S_IRUGO,
                         __stringify(IB_USER_VERBS_ABI_VERSION));
 
+static int ib_uverbs_create_uapi(struct ib_device *device,
+                                struct ib_uverbs_device *uverbs_dev)
+{
+       const struct uverbs_object_tree_def **specs;
+       struct uverbs_root_spec *specs_root;
+       unsigned int num_specs = 1;
+       unsigned int i;
+
+       if (device->driver_specs)
+               for (i = 0; device->driver_specs[i]; i++)
+                       num_specs++;
+
+       specs = kmalloc_array(num_specs, sizeof(*specs), GFP_KERNEL);
+       if (!specs)
+               return -ENOMEM;
+
+       specs[0] = uverbs_default_get_objects();
+       if (device->driver_specs)
+               for (i = 0; device->driver_specs[i]; i++)
+                       specs[i+1] = device->driver_specs[i];
+
+       specs_root = uverbs_alloc_spec_tree(num_specs, specs);
+       kfree(specs);
+       if (IS_ERR(specs_root))
+               return PTR_ERR(specs_root);
+
+       uverbs_dev->specs_root = specs_root;
+       return 0;
+}
+
 static void ib_uverbs_add_one(struct ib_device *device)
 {
        int devnum;
@@ -1036,6 +1066,9 @@ static void ib_uverbs_add_one(struct ib_device *device)
        rcu_assign_pointer(uverbs_dev->ib_dev, device);
        uverbs_dev->num_comp_vectors = device->num_comp_vectors;
 
+       if (ib_uverbs_create_uapi(device, uverbs_dev))
+               goto err;
+
        cdev_init(&uverbs_dev->cdev, NULL);
        uverbs_dev->cdev.owner = THIS_MODULE;
        uverbs_dev->cdev.ops = device->mmap ? &uverbs_mmap_fops : &uverbs_fops;
@@ -1055,23 +1088,6 @@ 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->driver_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;
-       } else {
-               uverbs_dev->specs_root = device->driver_specs_root;
-               /*
-                * Take responsibility to free the specs allocated by the
-                * driver.
-                */
-               device->driver_specs_root = NULL;
-       }
-
        ib_set_client_data(device, &uverbs_client, uverbs_dev);
 
        return;
index 3aa7c7deac749a5ef37951d81bc42990bed6165d..7f22b820a21ba0933884f49dd5d7123bf0cc4d3e 100644 (file)
@@ -316,4 +316,3 @@ const struct uverbs_object_tree_def *uverbs_default_get_objects(void)
 {
        return &uverbs_default_objects;
 }
-EXPORT_SYMBOL_GPL(uverbs_default_get_objects);
index 13744b4631b452bec3995048ecd880445c2e58f0..f86d831ee27c5d0482ba375051e549396175fc6d 100644 (file)
@@ -5523,37 +5523,29 @@ ADD_UVERBS_ATTRIBUTES_SIMPLE(
        UVERBS_ATTR_FLAGS_IN(MLX5_IB_ATTR_CREATE_FLOW_ACTION_FLAGS,
                             enum mlx5_ib_uapi_flow_action_flags));
 
-#define NUM_TREES      5
 static int populate_specs_root(struct mlx5_ib_dev *dev)
 {
-       const struct uverbs_object_tree_def *default_root[NUM_TREES + 1] = {
-               uverbs_default_get_objects()};
-       size_t num_trees = 1;
+       const struct uverbs_object_tree_def **trees = dev->driver_trees;
+       size_t num_trees = 0;
 
-       if (mlx5_accel_ipsec_device_caps(dev->mdev) & MLX5_ACCEL_IPSEC_CAP_DEVICE &&
-           !WARN_ON(num_trees >= ARRAY_SIZE(default_root)))
-               default_root[num_trees++] = &mlx5_ib_flow_action;
+       if (mlx5_accel_ipsec_device_caps(dev->mdev) &
+           MLX5_ACCEL_IPSEC_CAP_DEVICE)
+               trees[num_trees++] = &mlx5_ib_flow_action;
 
-       if (MLX5_CAP_DEV_MEM(dev->mdev, memic) &&
-           !WARN_ON(num_trees >= ARRAY_SIZE(default_root)))
-               default_root[num_trees++] = &mlx5_ib_dm;
+       if (MLX5_CAP_DEV_MEM(dev->mdev, memic))
+               trees[num_trees++] = &mlx5_ib_dm;
 
        if (MLX5_CAP_GEN_64(dev->mdev, general_obj_types) &
-                           MLX5_GENERAL_OBJ_TYPES_CAP_UCTX &&
-           !WARN_ON(num_trees >= ARRAY_SIZE(default_root)))
-               default_root[num_trees++] = mlx5_ib_get_devx_tree();
+           MLX5_GENERAL_OBJ_TYPES_CAP_UCTX)
+               trees[num_trees++] = mlx5_ib_get_devx_tree();
 
-       num_trees += mlx5_ib_get_flow_trees(default_root + num_trees);
+       num_trees += mlx5_ib_get_flow_trees(trees + num_trees);
 
-       dev->ib_dev.driver_specs_root =
-               uverbs_alloc_spec_tree(num_trees, default_root);
+       WARN_ON(num_trees >= ARRAY_SIZE(dev->driver_trees));
+       trees[num_trees] = NULL;
+       dev->ib_dev.driver_specs = trees;
 
-       return PTR_ERR_OR_ZERO(dev->ib_dev.driver_specs_root);
-}
-
-static void depopulate_specs_root(struct mlx5_ib_dev *dev)
-{
-       uverbs_free_spec_tree(dev->ib_dev.driver_specs_root);
+       return 0;
 }
 
 static int mlx5_ib_read_counters(struct ib_counters *counters,
@@ -6092,11 +6084,6 @@ int mlx5_ib_stage_ib_reg_init(struct mlx5_ib_dev *dev)
        return ib_register_device(&dev->ib_dev, NULL);
 }
 
-static void mlx5_ib_stage_depopulate_specs(struct mlx5_ib_dev *dev)
-{
-       depopulate_specs_root(dev);
-}
-
 void mlx5_ib_stage_pre_ib_reg_umr_cleanup(struct mlx5_ib_dev *dev)
 {
        destroy_umrc_res(dev);
@@ -6231,7 +6218,7 @@ static const struct mlx5_ib_profile pf_profile = {
                     mlx5_ib_stage_pre_ib_reg_umr_cleanup),
        STAGE_CREATE(MLX5_IB_STAGE_SPECS,
                     mlx5_ib_stage_populate_specs,
-                    mlx5_ib_stage_depopulate_specs),
+                    NULL),
        STAGE_CREATE(MLX5_IB_STAGE_IB_REG,
                     mlx5_ib_stage_ib_reg_init,
                     mlx5_ib_stage_ib_reg_cleanup),
@@ -6279,7 +6266,7 @@ static const struct mlx5_ib_profile nic_rep_profile = {
                     mlx5_ib_stage_pre_ib_reg_umr_cleanup),
        STAGE_CREATE(MLX5_IB_STAGE_SPECS,
                     mlx5_ib_stage_populate_specs,
-                    mlx5_ib_stage_depopulate_specs),
+                    NULL),
        STAGE_CREATE(MLX5_IB_STAGE_IB_REG,
                     mlx5_ib_stage_ib_reg_init,
                     mlx5_ib_stage_ib_reg_cleanup),
index b75754efc66309f7b6cd292dc9ea9f54626048bf..320d4dfe8c2f419cfdb9f53ddcdcc122eed294f1 100644 (file)
@@ -860,6 +860,7 @@ to_mcounters(struct ib_counters *ibcntrs)
 
 struct mlx5_ib_dev {
        struct ib_device                ib_dev;
+       const struct uverbs_object_tree_def *driver_trees[6];
        struct mlx5_core_dev            *mdev;
        struct mlx5_roce                roce[MLX5_MAX_PORTS];
        int                             num_ports;
index 4ffe3e11e8fb6ccefcc95f88db437e4fb098861a..3b07201b9a804e214ca900163468107c9ac8d6a1 100644 (file)
@@ -2580,7 +2580,7 @@ struct ib_device {
        const struct cpumask *(*get_vector_affinity)(struct ib_device *ibdev,
                                                     int comp_vector);
 
-       struct uverbs_root_spec         *driver_specs_root;
+       const struct uverbs_object_tree_def *const *driver_specs;
        enum rdma_driver_id             driver_id;
 };