diff options
Diffstat (limited to 'drivers/infiniband/core/sysfs.c')
| -rw-r--r-- | drivers/infiniband/core/sysfs.c | 58 | 
1 files changed, 36 insertions, 22 deletions
| diff --git a/drivers/infiniband/core/sysfs.c b/drivers/infiniband/core/sysfs.c index 6146c3c1cbe5..a3f84b50c46a 100644 --- a/drivers/infiniband/core/sysfs.c +++ b/drivers/infiniband/core/sysfs.c @@ -755,9 +755,9 @@ static void ib_port_release(struct kobject *kobj)  	for (i = 0; i != ARRAY_SIZE(port->groups); i++)  		kfree(port->groups[i].attrs);  	if (port->hw_stats_data) -		kfree(port->hw_stats_data->stats); +		rdma_free_hw_stats_struct(port->hw_stats_data->stats);  	kfree(port->hw_stats_data); -	kfree(port); +	kvfree(port);  }  static void ib_port_gid_attr_release(struct kobject *kobj) @@ -895,7 +895,7 @@ alloc_hw_stats_device(struct ib_device *ibdev)  	stats = ibdev->ops.alloc_hw_device_stats(ibdev);  	if (!stats)  		return ERR_PTR(-ENOMEM); -	if (!stats->names || stats->num_counters <= 0) +	if (!stats->descs || stats->num_counters <= 0)  		goto err_free_stats;  	/* @@ -911,7 +911,6 @@ alloc_hw_stats_device(struct ib_device *ibdev)  	if (!data->group.attrs)  		goto err_free_data; -	mutex_init(&stats->lock);  	data->group.name = "hw_counters";  	data->stats = stats;  	return data; @@ -919,14 +918,14 @@ alloc_hw_stats_device(struct ib_device *ibdev)  err_free_data:  	kfree(data);  err_free_stats: -	kfree(stats); +	rdma_free_hw_stats_struct(stats);  	return ERR_PTR(-ENOMEM);  }  void ib_device_release_hw_stats(struct hw_stats_device_data *data)  {  	kfree(data->group.attrs); -	kfree(data->stats); +	rdma_free_hw_stats_struct(data->stats);  	kfree(data);  } @@ -934,7 +933,8 @@ int ib_setup_device_attrs(struct ib_device *ibdev)  {  	struct hw_stats_device_attribute *attr;  	struct hw_stats_device_data *data; -	int i, ret; +	bool opstat_skipped = false; +	int i, ret, pos = 0;  	data = alloc_hw_stats_device(ibdev);  	if (IS_ERR(data)) { @@ -955,16 +955,23 @@ int ib_setup_device_attrs(struct ib_device *ibdev)  	data->stats->timestamp = jiffies;  	for (i = 0; i < data->stats->num_counters; i++) { -		attr = &data->attrs[i]; +		if (data->stats->descs[i].flags & IB_STAT_FLAG_OPTIONAL) { +			opstat_skipped = true; +			continue; +		} + +		WARN_ON(opstat_skipped); +		attr = &data->attrs[pos];  		sysfs_attr_init(&attr->attr.attr); -		attr->attr.attr.name = data->stats->names[i]; +		attr->attr.attr.name = data->stats->descs[i].name;  		attr->attr.attr.mode = 0444;  		attr->attr.show = hw_stat_device_show;  		attr->show = show_hw_stats; -		data->group.attrs[i] = &attr->attr.attr; +		data->group.attrs[pos] = &attr->attr.attr; +		pos++;  	} -	attr = &data->attrs[i]; +	attr = &data->attrs[pos];  	sysfs_attr_init(&attr->attr.attr);  	attr->attr.attr.name = "lifespan";  	attr->attr.attr.mode = 0644; @@ -972,7 +979,7 @@ int ib_setup_device_attrs(struct ib_device *ibdev)  	attr->show = show_stats_lifespan;  	attr->attr.store = hw_stat_device_store;  	attr->store = set_stats_lifespan; -	data->group.attrs[i] = &attr->attr.attr; +	data->group.attrs[pos] = &attr->attr.attr;  	for (i = 0; i != ARRAY_SIZE(ibdev->groups); i++)  		if (!ibdev->groups[i]) {  			ibdev->groups[i] = &data->group; @@ -994,7 +1001,7 @@ alloc_hw_stats_port(struct ib_port *port, struct attribute_group *group)  	stats = ibdev->ops.alloc_hw_port_stats(port->ibdev, port->port_num);  	if (!stats)  		return ERR_PTR(-ENOMEM); -	if (!stats->names || stats->num_counters <= 0) +	if (!stats->descs || stats->num_counters <= 0)  		goto err_free_stats;  	/* @@ -1010,7 +1017,6 @@ alloc_hw_stats_port(struct ib_port *port, struct attribute_group *group)  	if (!group->attrs)  		goto err_free_data; -	mutex_init(&stats->lock);  	group->name = "hw_counters";  	data->stats = stats;  	return data; @@ -1018,7 +1024,7 @@ alloc_hw_stats_port(struct ib_port *port, struct attribute_group *group)  err_free_data:  	kfree(data);  err_free_stats: -	kfree(stats); +	rdma_free_hw_stats_struct(stats);  	return ERR_PTR(-ENOMEM);  } @@ -1027,7 +1033,8 @@ static int setup_hw_port_stats(struct ib_port *port,  {  	struct hw_stats_port_attribute *attr;  	struct hw_stats_port_data *data; -	int i, ret; +	bool opstat_skipped = false; +	int i, ret, pos = 0;  	data = alloc_hw_stats_port(port, group);  	if (IS_ERR(data)) @@ -1045,16 +1052,23 @@ static int setup_hw_port_stats(struct ib_port *port,  	data->stats->timestamp = jiffies;  	for (i = 0; i < data->stats->num_counters; i++) { -		attr = &data->attrs[i]; +		if (data->stats->descs[i].flags & IB_STAT_FLAG_OPTIONAL) { +			opstat_skipped = true; +			continue; +		} + +		WARN_ON(opstat_skipped); +		attr = &data->attrs[pos];  		sysfs_attr_init(&attr->attr.attr); -		attr->attr.attr.name = data->stats->names[i]; +		attr->attr.attr.name = data->stats->descs[i].name;  		attr->attr.attr.mode = 0444;  		attr->attr.show = hw_stat_port_show;  		attr->show = show_hw_stats; -		group->attrs[i] = &attr->attr.attr; +		group->attrs[pos] = &attr->attr.attr; +		pos++;  	} -	attr = &data->attrs[i]; +	attr = &data->attrs[pos];  	sysfs_attr_init(&attr->attr.attr);  	attr->attr.attr.name = "lifespan";  	attr->attr.attr.mode = 0644; @@ -1062,7 +1076,7 @@ static int setup_hw_port_stats(struct ib_port *port,  	attr->show = show_stats_lifespan;  	attr->attr.store = hw_stat_port_store;  	attr->store = set_stats_lifespan; -	group->attrs[i] = &attr->attr.attr; +	group->attrs[pos] = &attr->attr.attr;  	port->hw_stats_data = data;  	return 0; @@ -1189,7 +1203,7 @@ static struct ib_port *setup_port(struct ib_core_device *coredev, int port_num,  	struct ib_port *p;  	int ret; -	p = kzalloc(struct_size(p, attrs_list, +	p = kvzalloc(struct_size(p, attrs_list,  				attr->gid_tbl_len + attr->pkey_tbl_len),  		    GFP_KERNEL);  	if (!p) |