init_port was only being used to register sysfs attributes against the port kobject. Now that all users are creating attribute_group's we can simply return the attribute_group list from the driver and the core code can handle it. This makes all the sysfs management quite straightforward and prevents any driver from abusing the naked port kobject in future because no driver code can access it. Signed-off-by: Jason Gunthorpe <jgg@xxxxxxxxxx> --- drivers/infiniband/core/device.c | 4 +-- drivers/infiniband/core/sysfs.c | 36 +++++++++------------------ drivers/infiniband/hw/hfi1/hfi.h | 4 +-- drivers/infiniband/hw/hfi1/sysfs.c | 10 +++----- drivers/infiniband/hw/hfi1/verbs.c | 2 +- drivers/infiniband/hw/qib/qib.h | 5 ++-- drivers/infiniband/hw/qib/qib_sysfs.c | 22 +++------------- drivers/infiniband/hw/qib/qib_verbs.c | 4 +-- drivers/infiniband/sw/rdmavt/vt.c | 2 +- include/rdma/ib_sysfs.h | 4 --- include/rdma/ib_verbs.h | 5 ++-- 11 files changed, 30 insertions(+), 68 deletions(-) diff --git a/drivers/infiniband/core/device.c b/drivers/infiniband/core/device.c index 030a4041b2e03b..28898558dda4c3 100644 --- a/drivers/infiniband/core/device.c +++ b/drivers/infiniband/core/device.c @@ -1703,7 +1703,7 @@ int ib_device_set_netns_put(struct sk_buff *skb, * port_cleanup infrastructure is implemented, this limitation will be * removed. */ - if (!dev->ops.disassociate_ucontext || dev->ops.init_port || + if (!dev->ops.disassociate_ucontext || dev->ops.get_port_groups || ib_devices_shared_netns) { ret = -EOPNOTSUPP; goto ns_err; @@ -2668,7 +2668,7 @@ void ib_set_device_ops(struct ib_device *dev, const struct ib_device_ops *ops) SET_DEVICE_OP(dev_ops, get_vf_config); SET_DEVICE_OP(dev_ops, get_vf_guid); SET_DEVICE_OP(dev_ops, get_vf_stats); - SET_DEVICE_OP(dev_ops, init_port); + SET_DEVICE_OP(dev_ops, get_port_groups); SET_DEVICE_OP(dev_ops, iw_accept); SET_DEVICE_OP(dev_ops, iw_add_ref); SET_DEVICE_OP(dev_ops, iw_connect); diff --git a/drivers/infiniband/core/sysfs.c b/drivers/infiniband/core/sysfs.c index 5d9c8bfc280d8f..595a3d22263bf0 100644 --- a/drivers/infiniband/core/sysfs.c +++ b/drivers/infiniband/core/sysfs.c @@ -69,6 +69,7 @@ struct ib_port { struct attribute_group groups[3]; const struct attribute_group *groups_list[5]; + const struct attribute_group **driver_groups; u32 port_num; struct port_table_attribute attrs_list[]; }; @@ -128,22 +129,6 @@ static ssize_t port_attr_store(struct kobject *kobj, return port_attr->store(p->ibdev, p->port_num, port_attr, buf, count); } -int ib_port_sysfs_create_groups(struct ib_device *ibdev, u32 port_num, - const struct attribute_group **groups) -{ - return sysfs_create_groups(&ibdev->port_data[port_num].sysfs->kobj, - groups); -} -EXPORT_SYMBOL(ib_port_sysfs_create_groups); - -void ib_port_sysfs_remove_groups(struct ib_device *ibdev, u32 port_num, - const struct attribute_group **groups) -{ - return sysfs_remove_groups(&ibdev->port_data[port_num].sysfs->kobj, - groups); -} -EXPORT_SYMBOL(ib_port_sysfs_remove_groups); - struct ib_device *ib_port_sysfs_get_ibdev_kobj(struct kobject *kobj, u32 *port_num) { @@ -1253,6 +1238,13 @@ static struct ib_port *setup_port(struct ib_core_device *coredev, int port_num, ret = sysfs_create_groups(&p->kobj, p->groups_list); if (ret) goto err_del; + if (device->ops.get_port_groups && is_full_dev) { + p->driver_groups = + device->ops.get_port_groups(device, port_num); + ret = sysfs_create_groups(&p->kobj, p->driver_groups); + if (ret) + goto err_groups; + } list_add_tail(&p->kobj.entry, &coredev->port_list); if (device->port_data && is_full_dev) @@ -1260,6 +1252,8 @@ static struct ib_port *setup_port(struct ib_core_device *coredev, int port_num, return p; +err_groups: + sysfs_remove_groups(&p->kobj, p->groups_list); err_del: kobject_del(&p->kobj); err_put: @@ -1273,6 +1267,8 @@ static void destroy_port(struct ib_port *port) port->ibdev->port_data[port->port_num].sysfs == port) port->ibdev->port_data[port->port_num].sysfs = NULL; list_del(&port->kobj.entry); + if (port->driver_groups) + sysfs_remove_groups(&port->kobj, port->driver_groups); sysfs_remove_groups(&port->kobj, port->groups_list); kobject_del(&port->kobj); kobject_put(&port->kobj); @@ -1407,7 +1403,6 @@ void ib_free_port_attrs(struct ib_core_device *coredev) int ib_setup_port_attrs(struct ib_core_device *coredev) { struct ib_device *device = rdma_device_to_ibdev(&coredev->dev); - bool is_full_dev = &device->coredev == coredev; u32 port_num; int ret; @@ -1433,13 +1428,6 @@ int ib_setup_port_attrs(struct ib_core_device *coredev) ret = setup_gid_attrs(port, &attr); if (ret) goto err_put; - - if (device->ops.init_port && is_full_dev) { - ret = device->ops.init_port(device, port_num, - &port->kobj); - if (ret) - goto err_put; - } } return 0; diff --git a/drivers/infiniband/hw/hfi1/hfi.h b/drivers/infiniband/hw/hfi1/hfi.h index 87e101fb1f658a..d0d86af19fbf3d 100644 --- a/drivers/infiniband/hw/hfi1/hfi.h +++ b/drivers/infiniband/hw/hfi1/hfi.h @@ -2188,8 +2188,8 @@ extern const struct attribute_group ib_hfi1_attr_group; int hfi1_device_create(struct hfi1_devdata *dd); void hfi1_device_remove(struct hfi1_devdata *dd); -int hfi1_create_port_files(struct ib_device *ibdev, u32 port_num, - struct kobject *kobj); +const struct attribute_group **hfi1_get_port_groups(struct ib_device *ibdev, + u32 port_num); int hfi1_verbs_register_sysfs(struct hfi1_devdata *dd); void hfi1_verbs_unregister_sysfs(struct hfi1_devdata *dd); /* Hook for sysfs read of QSFP */ diff --git a/drivers/infiniband/hw/hfi1/sysfs.c b/drivers/infiniband/hw/hfi1/sysfs.c index 326c6c2842f2f3..b299ae37023d32 100644 --- a/drivers/infiniband/hw/hfi1/sysfs.c +++ b/drivers/infiniband/hw/hfi1/sysfs.c @@ -606,10 +606,10 @@ static const struct attribute_group *hfi1_port_groups[] = { NULL, }; -int hfi1_create_port_files(struct ib_device *ibdev, u32 port_num, - struct kobject *kobj) +const struct attribute_group **hfi1_get_port_groups(struct ib_device *ibdev, + u32 port_num) { - return ib_port_sysfs_create_groups(ibdev, port_num, hfi1_port_groups); + return hfi1_port_groups; } struct sde_attribute { @@ -740,8 +740,4 @@ void hfi1_verbs_unregister_sysfs(struct hfi1_devdata *dd) /* Unwind operations in hfi1_verbs_register_sysfs() */ for (i = 0; i < dd->num_sdma; i++) kobject_put(&dd->per_sdma[i].kobj); - - for (i = 0; i < dd->num_pports; i++) - ib_port_sysfs_remove_groups(&dd->verbs_dev.rdi.ibdev, i + 1, - hfi1_port_groups); } diff --git a/drivers/infiniband/hw/hfi1/verbs.c b/drivers/infiniband/hw/hfi1/verbs.c index 85deba07a6754b..33c757e6b88d30 100644 --- a/drivers/infiniband/hw/hfi1/verbs.c +++ b/drivers/infiniband/hw/hfi1/verbs.c @@ -1791,7 +1791,7 @@ static const struct ib_device_ops hfi1_dev_ops = { .alloc_rdma_netdev = hfi1_vnic_alloc_rn, .get_dev_fw_str = hfi1_get_dev_fw_str, .get_hw_stats = get_hw_stats, - .init_port = hfi1_create_port_files, + .get_port_groups = hfi1_get_port_groups, .modify_device = modify_device, /* keep process mad in the driver */ .process_mad = hfi1_process_mad, diff --git a/drivers/infiniband/hw/qib/qib.h b/drivers/infiniband/hw/qib/qib.h index 3decd6d0843172..d07b766d50fabc 100644 --- a/drivers/infiniband/hw/qib/qib.h +++ b/drivers/infiniband/hw/qib/qib.h @@ -1366,9 +1366,8 @@ extern const struct attribute_group qib_attr_group; int qib_device_create(struct qib_devdata *); void qib_device_remove(struct qib_devdata *); -int qib_create_port_files(struct ib_device *ibdev, u32 port_num, - struct kobject *kobj); -void qib_verbs_unregister_sysfs(struct qib_devdata *); +const struct attribute_group **qib_get_port_groups(struct ib_device *ibdev, + u32 port_num); /* Hook for sysfs read of QSFP */ extern int qib_qsfp_dump(struct qib_pportdata *ppd, char *buf, int len); diff --git a/drivers/infiniband/hw/qib/qib_sysfs.c b/drivers/infiniband/hw/qib/qib_sysfs.c index 2c81285d245fa7..835684d43e09f0 100644 --- a/drivers/infiniband/hw/qib/qib_sysfs.c +++ b/drivers/infiniband/hw/qib/qib_sysfs.c @@ -715,8 +715,8 @@ const struct attribute_group qib_attr_group = { .attrs = qib_attributes, }; -int qib_create_port_files(struct ib_device *ibdev, u32 port_num, - struct kobject *kobj) +const struct attribute_group **qib_get_port_groups(struct ib_device *ibdev, + u32 port_num) { struct qib_devdata *dd = dd_from_ibdev(ibdev); struct qib_pportdata *ppd = &dd->pport[port_num - 1]; @@ -729,21 +729,5 @@ int qib_create_port_files(struct ib_device *ibdev, u32 port_num, if (qib_cc_table_size && ppd->congestion_entries_shadow) *cur_group++ = &port_ccmgta_attribute_group; - - return ib_port_sysfs_create_groups(ibdev, port_num, ppd->groups); -} - -/* - * Unregister and remove our files in /sys/class/infiniband. - */ -void qib_verbs_unregister_sysfs(struct qib_devdata *dd) -{ - int i; - - for (i = 0; i < dd->num_pports; i++) { - struct qib_pportdata *ppd = &dd->pport[i]; - - ib_port_sysfs_remove_groups(&dd->verbs_dev.rdi.ibdev, i, - ppd->groups); - } + return ppd->groups; } diff --git a/drivers/infiniband/hw/qib/qib_verbs.c b/drivers/infiniband/hw/qib/qib_verbs.c index d17d034ecdfd9f..5552440f843bb1 100644 --- a/drivers/infiniband/hw/qib/qib_verbs.c +++ b/drivers/infiniband/hw/qib/qib_verbs.c @@ -1483,7 +1483,7 @@ static const struct ib_device_ops qib_dev_ops = { .owner = THIS_MODULE, .driver_id = RDMA_DRIVER_QIB, - .init_port = qib_create_port_files, + .get_port_groups = qib_get_port_groups, .modify_device = qib_modify_device, .process_mad = qib_process_mad, }; @@ -1644,8 +1644,6 @@ void qib_unregister_ib_device(struct qib_devdata *dd) { struct qib_ibdev *dev = &dd->verbs_dev; - qib_verbs_unregister_sysfs(dd); - rvt_unregister_device(&dd->verbs_dev.rdi); if (!list_empty(&dev->piowait)) diff --git a/drivers/infiniband/sw/rdmavt/vt.c b/drivers/infiniband/sw/rdmavt/vt.c index 12ebe041a5da9b..e701ceff449b4a 100644 --- a/drivers/infiniband/sw/rdmavt/vt.c +++ b/drivers/infiniband/sw/rdmavt/vt.c @@ -418,7 +418,7 @@ static noinline int check_support(struct rvt_dev_info *rdi, int verb) * These functions are not part of verbs specifically but are * required for rdmavt to function. */ - if ((!rdi->ibdev.ops.init_port) || + if ((!rdi->ibdev.ops.get_port_groups) || (!rdi->driver_f.get_pci_dev)) return -EINVAL; break; diff --git a/include/rdma/ib_sysfs.h b/include/rdma/ib_sysfs.h index f869d0e4fd3030..3b77cfd74d9a30 100644 --- a/include/rdma/ib_sysfs.h +++ b/include/rdma/ib_sysfs.h @@ -31,10 +31,6 @@ struct ib_port_attribute { #define IB_PORT_ATTR_WO(_name) \ struct ib_port_attribute ib_port_attr_##_name = __ATTR_WO(_name) -int ib_port_sysfs_create_groups(struct ib_device *ibdev, u32 port_num, - const struct attribute_group **groups); -void ib_port_sysfs_remove_groups(struct ib_device *ibdev, u32 port_num, - const struct attribute_group **groups); struct ib_device *ib_port_sysfs_get_ibdev_kobj(struct kobject *kobj, u32 *port_num); diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h index 5f70aab1f8663b..5120a279a685e7 100644 --- a/include/rdma/ib_verbs.h +++ b/include/rdma/ib_verbs.h @@ -2551,8 +2551,9 @@ struct ib_device_ops { * This function is called once for each port when a ib device is * registered. */ - int (*init_port)(struct ib_device *device, u32 port_num, - struct kobject *port_sysfs); + const struct attribute_group **(*get_port_groups)( + struct ib_device *device, u32 port_num); + /** * Allows rdma drivers to add their own restrack attributes. */ -- 2.31.1