From: Parav Pandit <parav@xxxxxxxxxxxx> Refactor code for device and port attributes for reuse. while at it, rename counter part free function to ib_free_port_attrs. Also attribute setup sequence is: (a) port specific init. (b) device stats alloc/init. So for cleanup, follow reverse sequence: (a) device stats dealloc (b) port specific cleanup Signed-off-by: Parav Pandit <parav@xxxxxxxxxxxx> Signed-off-by: Leon Romanovsky <leonro@xxxxxxxxxxxx> --- drivers/infiniband/core/sysfs.c | 69 ++++++++++++++++++--------------- 1 file changed, 38 insertions(+), 31 deletions(-) diff --git a/drivers/infiniband/core/sysfs.c b/drivers/infiniband/core/sysfs.c index 80f68eb0ba5c..9b6eef793475 100644 --- a/drivers/infiniband/core/sysfs.c +++ b/drivers/infiniband/core/sysfs.c @@ -1281,17 +1281,17 @@ static const struct attribute_group dev_attr_group = { .attrs = ib_dev_attrs, }; -static void free_port_list_attributes(struct ib_device *device) +static void ib_free_port_attrs(struct ib_device *device) { struct kobject *p, *t; list_for_each_entry_safe(p, t, &device->port_list, entry) { struct ib_port *port = container_of(p, struct ib_port, kobj); + list_del(&p->entry); - if (port->hw_stats) { - kfree(port->hw_stats); + if (port->hw_stats_ag) free_hsag(&port->kobj, port->hw_stats_ag); - } + kfree(port->hw_stats); if (port->pma_table) sysfs_remove_group(p, port->pma_table); @@ -1308,26 +1308,16 @@ static void free_port_list_attributes(struct ib_device *device) kobject_put(device->ports_kobj); } -int ib_device_register_sysfs(struct ib_device *device, - int (*port_callback)(struct ib_device *, - u8, struct kobject *)) +static int ib_setup_port_attrs(struct ib_device *device, + int (*port_callback)(struct ib_device *, + u8, struct kobject *)) { - struct device *class_dev = &device->dev; int ret; int i; - device->groups[0] = &dev_attr_group; - class_dev->groups = device->groups; - - ret = device_add(class_dev); - if (ret) - goto err; - - device->ports_kobj = kobject_create_and_add("ports", &class_dev->kobj); - if (!device->ports_kobj) { - ret = -ENOMEM; - goto err_put; - } + device->ports_kobj = kobject_create_and_add("ports", &device->dev.kobj); + if (!device->ports_kobj) + return -ENOMEM; if (rdma_cap_ib_switch(device)) { ret = add_port(device, 0, port_callback); @@ -1341,29 +1331,46 @@ int ib_device_register_sysfs(struct ib_device *device, } } - if (device->ops.alloc_hw_stats) - setup_hw_stats(device, NULL, 0); - return 0; err_put: - free_port_list_attributes(device); - device_del(class_dev); -err: + ib_free_port_attrs(device); return ret; } +int ib_device_register_sysfs(struct ib_device *device, + int (*port_callback)(struct ib_device *, + u8, struct kobject *)) +{ + int ret; + + device->groups[0] = &dev_attr_group; + device->dev.groups = device->groups; + + ret = device_add(&device->dev); + if (ret) + return ret; + + ret = ib_setup_port_attrs(device, port_callback); + if (ret) { + device_del(&device->dev); + return ret; + } + if (device->ops.alloc_hw_stats) + setup_hw_stats(device, NULL, 0); + + return 0; +} + void ib_device_unregister_sysfs(struct ib_device *device) { /* Hold device until ib_dealloc_device() */ get_device(&device->dev); - free_port_list_attributes(device); - - if (device->hw_stats) { - kfree(device->hw_stats); + if (device->hw_stats_ag) free_hsag(&device->dev.kobj, device->hw_stats_ag); - } + kfree(device->hw_stats); + ib_free_port_attrs(device); device_unregister(&device->dev); } -- 2.19.1