]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
RDMA/core: Introduce ib_core_device to hold device
authorParav Pandit <parav@mellanox.com>
Tue, 26 Feb 2019 11:56:11 +0000 (13:56 +0200)
committerJason Gunthorpe <jgg@mellanox.com>
Thu, 28 Mar 2019 17:52:02 +0000 (14:52 -0300)
In order to support sysfs entries in multiple net namespaces for a rdma
device, introduce a ib_core_device whose scope is limited to hold core
device and per port sysfs related entries.

This is preparation patch so that multiple ib_core_devices in each net
namespace can be created in subsequent patch who all can share ib_device.

(a) Move sysfs specific fields to ib_core_device.
(b) Make sysfs and device life cycle related routines to work on
    ib_core_device.
(c) Introduce and use rdma_init_coredev() helper to initialize
    coredev fields.

Signed-off-by: Parav Pandit <parav@mellanox.com>
Signed-off-by: Leon Romanovsky <leonro@mellanox.com>
Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
drivers/infiniband/core/device.c
drivers/infiniband/core/sysfs.c
include/rdma/ib_verbs.h

index 7421ec4883fb0339dc67324b286baca87b03fdb4..31229074981dd0ccbdaf11b9c29ef437275136cb 100644 (file)
@@ -363,6 +363,25 @@ static struct class ib_class = {
        .dev_uevent = ib_device_uevent,
 };
 
+static void rdma_init_coredev(struct ib_core_device *coredev,
+                             struct ib_device *dev)
+{
+       /* This BUILD_BUG_ON is intended to catch layout change
+        * of union of ib_core_device and device.
+        * dev must be the first element as ib_core and providers
+        * driver uses it. Adding anything in ib_core_device before
+        * device will break this assumption.
+        */
+       BUILD_BUG_ON(offsetof(struct ib_device, coredev.dev) !=
+                    offsetof(struct ib_device, dev));
+
+       coredev->dev.class = &ib_class;
+       coredev->dev.groups = dev->groups;
+       device_initialize(&coredev->dev);
+       coredev->owner = dev;
+       INIT_LIST_HEAD(&coredev->port_list);
+}
+
 /**
  * _ib_alloc_device - allocate an IB device struct
  * @size:size of structure to allocate
@@ -389,10 +408,8 @@ struct ib_device *_ib_alloc_device(size_t size)
                return NULL;
        }
 
-       device->dev.class = &ib_class;
        device->groups[0] = &ib_dev_attr_group;
-       device->dev.groups = device->groups;
-       device_initialize(&device->dev);
+       rdma_init_coredev(&device->coredev, device);
 
        INIT_LIST_HEAD(&device->event_handler_list);
        spin_lock_init(&device->event_handler_lock);
@@ -403,7 +420,6 @@ struct ib_device *_ib_alloc_device(size_t size)
         */
        xa_init_flags(&device->client_data, XA_FLAGS_ALLOC);
        init_rwsem(&device->client_data_rwsem);
-       INIT_LIST_HEAD(&device->port_list);
        init_completion(&device->unreg_completion);
        INIT_WORK(&device->unregistration_work, ib_unregister_work);
 
index 9b6a065bdfa509814ce3f24fe610fd55c2a01f67..46ac766af1106bbc339e3df4d7f728d999abb37e 100644 (file)
@@ -1015,8 +1015,9 @@ static void setup_hw_stats(struct ib_device *device, struct ib_port *port,
        return;
 }
 
-static int add_port(struct ib_device *device, int port_num)
+static int add_port(struct ib_core_device *coredev, int port_num)
 {
+       struct ib_device *device = rdma_device_to_ibdev(&coredev->dev);
        struct ib_port *p;
        struct ib_port_attr attr;
        int i;
@@ -1034,7 +1035,7 @@ static int add_port(struct ib_device *device, int port_num)
        p->port_num   = port_num;
 
        ret = kobject_init_and_add(&p->kobj, &port_type,
-                                  device->ports_kobj,
+                                  coredev->ports_kobj,
                                   "%d", port_num);
        if (ret) {
                kfree(p);
@@ -1125,7 +1126,7 @@ static int add_port(struct ib_device *device, int port_num)
        if (device->ops.alloc_hw_stats && port_num)
                setup_hw_stats(device, p, port_num);
 
-       list_add_tail(&p->kobj.entry, &device->port_list);
+       list_add_tail(&p->kobj.entry, &coredev->port_list);
 
        kobject_uevent(&p->kobj, KOBJ_ADD);
        return 0;
@@ -1279,11 +1280,11 @@ const struct attribute_group ib_dev_attr_group = {
        .attrs = ib_dev_attrs,
 };
 
-static void ib_free_port_attrs(struct ib_device *device)
+static void ib_free_port_attrs(struct ib_core_device *coredev)
 {
        struct kobject *p, *t;
 
-       list_for_each_entry_safe(p, t, &device->port_list, entry) {
+       list_for_each_entry_safe(p, t, &coredev->port_list, entry) {
                struct ib_port *port = container_of(p, struct ib_port, kobj);
 
                list_del(&p->entry);
@@ -1303,20 +1304,22 @@ static void ib_free_port_attrs(struct ib_device *device)
                kobject_put(p);
        }
 
-       kobject_put(device->ports_kobj);
+       kobject_put(coredev->ports_kobj);
 }
 
-static int ib_setup_port_attrs(struct ib_device *device)
+static int ib_setup_port_attrs(struct ib_core_device *coredev)
 {
+       struct ib_device *device = rdma_device_to_ibdev(&coredev->dev);
        unsigned int port;
        int ret;
 
-       device->ports_kobj = kobject_create_and_add("ports", &device->dev.kobj);
-       if (!device->ports_kobj)
+       coredev->ports_kobj = kobject_create_and_add("ports",
+                                                    &coredev->dev.kobj);
+       if (!coredev->ports_kobj)
                return -ENOMEM;
 
        rdma_for_each_port (device, port) {
-               ret = add_port(device, port);
+               ret = add_port(coredev, port);
                if (ret)
                        goto err_put;
        }
@@ -1324,7 +1327,7 @@ static int ib_setup_port_attrs(struct ib_device *device)
        return 0;
 
 err_put:
-       ib_free_port_attrs(device);
+       ib_free_port_attrs(coredev);
        return ret;
 }
 
@@ -1332,7 +1335,7 @@ int ib_device_register_sysfs(struct ib_device *device)
 {
        int ret;
 
-       ret = ib_setup_port_attrs(device);
+       ret = ib_setup_port_attrs(&device->coredev);
        if (ret)
                return ret;
 
@@ -1348,5 +1351,5 @@ void ib_device_unregister_sysfs(struct ib_device *device)
                free_hsag(&device->dev.kobj, device->hw_stats_ag);
        kfree(device->hw_stats);
 
-       ib_free_port_attrs(device);
+       ib_free_port_attrs(&device->coredev);
 }
index 9b9e17bcc201d394e3010b782536eddc62883d3e..5f9f4fcdc4ccc7be7c1aa219591be8628f29714c 100644 (file)
@@ -2554,8 +2554,17 @@ struct ib_device_ops {
        DECLARE_RDMA_OBJ_SIZE(ib_ucontext);
 };
 
-struct rdma_restrack_root;
+struct ib_core_device {
+       /* device must be the first element in structure until,
+        * union of ib_core_device and device exists in ib_device.
+        */
+       struct device dev;
+       struct kobject *ports_kobj;
+       struct list_head port_list;
+       struct ib_device *owner; /* reach back to owner ib_device */
+};
 
+struct rdma_restrack_root;
 struct ib_device {
        /* Do not access @dma_device directly from ULP nor from HW drivers. */
        struct device                *dma_device;
@@ -2581,16 +2590,17 @@ struct ib_device {
        struct iw_cm_verbs           *iwcm;
 
        struct module               *owner;
-       struct device                dev;
+       union {
+               struct device           dev;
+               struct ib_core_device   coredev;
+       };
+
        /* First group for device attributes,
         * Second group for driver provided attributes (optional).
         * It is NULL terminated array.
         */
        const struct attribute_group    *groups[3];
 
-       struct kobject                  *ports_kobj;
-       struct list_head             port_list;
-
        int                          uverbs_abi_ver;
        u64                          uverbs_cmd_mask;
        u64                          uverbs_ex_cmd_mask;
@@ -4349,7 +4359,10 @@ rdma_set_device_sysfs_group(struct ib_device *dev,
  */
 static inline struct ib_device *rdma_device_to_ibdev(struct device *device)
 {
-       return container_of(device, struct ib_device, dev);
+       struct ib_core_device *coredev =
+               container_of(device, struct ib_core_device, dev);
+
+       return coredev->owner;
 }
 
 /**