提交 b7066b32 编写于 作者: J Jason Gunthorpe

RDMA/core: Create the device hw_counters through the normal groups mechanism

Instead of calling device_add_groups() add the group to the existing
groups array which is managed through device_add().

This requires setting up the hw_counters before device_add(), so it gets
split up from the already split port sysfs flow.

Move all the memory freeing to the release function.

Link: https://lore.kernel.org/r/666250d937b64f6fdf45da9e2dc0b6e5e4f7abd8.1623427137.git.leonro@nvidia.comSigned-off-by: NLeon Romanovsky <leonro@nvidia.com>
Signed-off-by: NJason Gunthorpe <jgg@nvidia.com>
上级 2ca1cca4
...@@ -78,8 +78,6 @@ static inline struct rdma_dev_net *rdma_net_to_dev_net(struct net *net) ...@@ -78,8 +78,6 @@ static inline struct rdma_dev_net *rdma_net_to_dev_net(struct net *net)
return net_generic(net, rdma_dev_net_id); return net_generic(net, rdma_dev_net_id);
} }
int ib_device_register_sysfs(struct ib_device *device);
void ib_device_unregister_sysfs(struct ib_device *device);
int ib_device_rename(struct ib_device *ibdev, const char *name); int ib_device_rename(struct ib_device *ibdev, const char *name);
int ib_device_set_dim(struct ib_device *ibdev, u8 use_dim); int ib_device_set_dim(struct ib_device *ibdev, u8 use_dim);
...@@ -379,6 +377,8 @@ struct net_device *rdma_read_gid_attr_ndev_rcu(const struct ib_gid_attr *attr); ...@@ -379,6 +377,8 @@ struct net_device *rdma_read_gid_attr_ndev_rcu(const struct ib_gid_attr *attr);
void ib_free_port_attrs(struct ib_core_device *coredev); void ib_free_port_attrs(struct ib_core_device *coredev);
int ib_setup_port_attrs(struct ib_core_device *coredev); int ib_setup_port_attrs(struct ib_core_device *coredev);
struct rdma_hw_stats *ib_get_hw_stats_port(struct ib_device *ibdev, u32 port_num); struct rdma_hw_stats *ib_get_hw_stats_port(struct ib_device *ibdev, u32 port_num);
void ib_device_release_hw_stats(struct hw_stats_device_data *data);
int ib_setup_device_attrs(struct ib_device *ibdev);
int rdma_compatdev_set(u8 enable); int rdma_compatdev_set(u8 enable);
......
...@@ -491,6 +491,8 @@ static void ib_device_release(struct device *device) ...@@ -491,6 +491,8 @@ static void ib_device_release(struct device *device)
free_netdevs(dev); free_netdevs(dev);
WARN_ON(refcount_read(&dev->refcount)); WARN_ON(refcount_read(&dev->refcount));
if (dev->hw_stats_data)
ib_device_release_hw_stats(dev->hw_stats_data);
if (dev->port_data) { if (dev->port_data) {
ib_cache_release_one(dev); ib_cache_release_one(dev);
ib_security_release_port_pkey_list(dev); ib_security_release_port_pkey_list(dev);
...@@ -1394,6 +1396,10 @@ int ib_register_device(struct ib_device *device, const char *name, ...@@ -1394,6 +1396,10 @@ int ib_register_device(struct ib_device *device, const char *name,
return ret; return ret;
} }
ret = ib_setup_device_attrs(device);
if (ret)
goto cache_cleanup;
ib_device_register_rdmacg(device); ib_device_register_rdmacg(device);
rdma_counter_init(device); rdma_counter_init(device);
...@@ -1407,7 +1413,7 @@ int ib_register_device(struct ib_device *device, const char *name, ...@@ -1407,7 +1413,7 @@ int ib_register_device(struct ib_device *device, const char *name,
if (ret) if (ret)
goto cg_cleanup; goto cg_cleanup;
ret = ib_device_register_sysfs(device); ret = ib_setup_port_attrs(&device->coredev);
if (ret) { if (ret) {
dev_warn(&device->dev, dev_warn(&device->dev,
"Couldn't register device with driver model\n"); "Couldn't register device with driver model\n");
...@@ -1449,6 +1455,7 @@ int ib_register_device(struct ib_device *device, const char *name, ...@@ -1449,6 +1455,7 @@ int ib_register_device(struct ib_device *device, const char *name,
cg_cleanup: cg_cleanup:
dev_set_uevent_suppress(&device->dev, false); dev_set_uevent_suppress(&device->dev, false);
ib_device_unregister_rdmacg(device); ib_device_unregister_rdmacg(device);
cache_cleanup:
ib_cache_cleanup_one(device); ib_cache_cleanup_one(device);
return ret; return ret;
} }
...@@ -1473,7 +1480,7 @@ static void __ib_unregister_device(struct ib_device *ib_dev) ...@@ -1473,7 +1480,7 @@ static void __ib_unregister_device(struct ib_device *ib_dev)
/* Expedite removing unregistered pointers from the hash table */ /* Expedite removing unregistered pointers from the hash table */
free_netdevs(ib_dev); free_netdevs(ib_dev);
ib_device_unregister_sysfs(ib_dev); ib_free_port_attrs(&ib_dev->coredev);
device_del(&ib_dev->dev); device_del(&ib_dev->dev);
ib_device_unregister_rdmacg(ib_dev); ib_device_unregister_rdmacg(ib_dev);
ib_cache_cleanup_one(ib_dev); ib_cache_cleanup_one(ib_dev);
......
...@@ -107,7 +107,6 @@ struct hw_stats_port_attribute { ...@@ -107,7 +107,6 @@ struct hw_stats_port_attribute {
struct hw_stats_device_data { struct hw_stats_device_data {
struct attribute_group group; struct attribute_group group;
const struct attribute_group *groups[2];
struct rdma_hw_stats *stats; struct rdma_hw_stats *stats;
struct hw_stats_device_attribute attrs[]; struct hw_stats_device_attribute attrs[];
}; };
...@@ -915,7 +914,6 @@ alloc_hw_stats_device(struct ib_device *ibdev) ...@@ -915,7 +914,6 @@ alloc_hw_stats_device(struct ib_device *ibdev)
mutex_init(&stats->lock); mutex_init(&stats->lock);
data->group.name = "hw_counters"; data->group.name = "hw_counters";
data->stats = stats; data->stats = stats;
data->groups[0] = &data->group;
return data; return data;
err_free_data: err_free_data:
...@@ -925,29 +923,33 @@ alloc_hw_stats_device(struct ib_device *ibdev) ...@@ -925,29 +923,33 @@ alloc_hw_stats_device(struct ib_device *ibdev)
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
} }
static void free_hw_stats_device(struct hw_stats_device_data *data) void ib_device_release_hw_stats(struct hw_stats_device_data *data)
{ {
kfree(data->group.attrs); kfree(data->group.attrs);
kfree(data->stats); kfree(data->stats);
kfree(data); kfree(data);
} }
static int setup_hw_device_stats(struct ib_device *ibdev) int ib_setup_device_attrs(struct ib_device *ibdev)
{ {
struct hw_stats_device_attribute *attr; struct hw_stats_device_attribute *attr;
struct hw_stats_device_data *data; struct hw_stats_device_data *data;
int i, ret; int i, ret;
data = alloc_hw_stats_device(ibdev); data = alloc_hw_stats_device(ibdev);
if (IS_ERR(data)) if (IS_ERR(data)) {
if (PTR_ERR(data) == -EOPNOTSUPP)
return 0;
return PTR_ERR(data); return PTR_ERR(data);
}
ibdev->hw_stats_data = data;
ret = ibdev->ops.get_hw_stats(ibdev, data->stats, 0, ret = ibdev->ops.get_hw_stats(ibdev, data->stats, 0,
data->stats->num_counters); data->stats->num_counters);
if (ret != data->stats->num_counters) { if (ret != data->stats->num_counters) {
if (WARN_ON(ret >= 0)) if (WARN_ON(ret >= 0))
ret = -EINVAL; return -EINVAL;
goto err_free; return ret;
} }
data->stats->timestamp = jiffies; data->stats->timestamp = jiffies;
...@@ -971,26 +973,13 @@ static int setup_hw_device_stats(struct ib_device *ibdev) ...@@ -971,26 +973,13 @@ static int setup_hw_device_stats(struct ib_device *ibdev)
attr->attr.store = hw_stat_device_store; attr->attr.store = hw_stat_device_store;
attr->store = set_stats_lifespan; attr->store = set_stats_lifespan;
data->group.attrs[i] = &attr->attr.attr; data->group.attrs[i] = &attr->attr.attr;
for (i = 0; i != ARRAY_SIZE(ibdev->groups); i++)
ibdev->hw_stats_data = data; if (!ibdev->groups[i]) {
ret = device_add_groups(&ibdev->dev, data->groups); ibdev->groups[i] = &data->group;
if (ret) return 0;
goto err_free; }
return 0; WARN(true, "struct ib_device->groups is too small");
return -EINVAL;
err_free:
free_hw_stats_device(data);
ibdev->hw_stats_data = NULL;
return ret;
}
static void destroy_hw_device_stats(struct ib_device *ibdev)
{
if (!ibdev->hw_stats_data)
return;
device_remove_groups(&ibdev->dev, ibdev->hw_stats_data->groups);
free_hw_stats_device(ibdev->hw_stats_data);
ibdev->hw_stats_data = NULL;
} }
static struct hw_stats_port_data * static struct hw_stats_port_data *
...@@ -1443,29 +1432,6 @@ int ib_setup_port_attrs(struct ib_core_device *coredev) ...@@ -1443,29 +1432,6 @@ int ib_setup_port_attrs(struct ib_core_device *coredev)
return ret; return ret;
} }
int ib_device_register_sysfs(struct ib_device *device)
{
int ret;
ret = ib_setup_port_attrs(&device->coredev);
if (ret)
return ret;
ret = setup_hw_device_stats(device);
if (ret && ret != -EOPNOTSUPP) {
ib_free_port_attrs(&device->coredev);
return ret;
}
return 0;
}
void ib_device_unregister_sysfs(struct ib_device *device)
{
destroy_hw_device_stats(device);
ib_free_port_attrs(&device->coredev);
}
/** /**
* ib_port_register_module_stat - add module counters under relevant port * ib_port_register_module_stat - add module counters under relevant port
* of IB device. * of IB device.
......
...@@ -2677,11 +2677,12 @@ struct ib_device { ...@@ -2677,11 +2677,12 @@ struct ib_device {
struct ib_core_device coredev; struct ib_core_device coredev;
}; };
/* First group for device attributes, /* First group is for device attributes,
* Second group for driver provided attributes (optional). * Second group is for driver provided attributes (optional).
* It is NULL terminated array. * Third group is for the hw_stats
* It is a NULL terminated array.
*/ */
const struct attribute_group *groups[3]; const struct attribute_group *groups[4];
u64 uverbs_cmd_mask; u64 uverbs_cmd_mask;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册