Commit d5a8aa5d authored by Rafael J. Wysocki's avatar Rafael J. Wysocki

thermal: sysfs: Fix cooling_device_stats_setup() error code path

If cooling_device_stats_setup() fails to create the stats object, it
must clear the last slot in cooling_device_attr_groups that was
initially empty (so as to make it possible to add stats attributes to
the cooling device attribute groups).

Failing to do so may cause the stats attributes to be created by
mistake for a device that doesn't have a stats object, because the
slot in question might be populated previously during the registration
of another cooling device.

Fixes: 8ea22951 ("thermal: Add cooling device's statistics in sysfs")
Reported-by: default avatarDi Shen <di.shen@unisoc.com>
Tested-by: default avatarDi Shen <di.shen@unisoc.com>
Cc: 4.17+ <stable@vger.kernel.org> # 4.17+
Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
parent c1dbe9a1
...@@ -813,12 +813,13 @@ static const struct attribute_group cooling_device_stats_attr_group = { ...@@ -813,12 +813,13 @@ static const struct attribute_group cooling_device_stats_attr_group = {
static void cooling_device_stats_setup(struct thermal_cooling_device *cdev) static void cooling_device_stats_setup(struct thermal_cooling_device *cdev)
{ {
const struct attribute_group *stats_attr_group = NULL;
struct cooling_dev_stats *stats; struct cooling_dev_stats *stats;
unsigned long states; unsigned long states;
int var; int var;
if (cdev->ops->get_max_state(cdev, &states)) if (cdev->ops->get_max_state(cdev, &states))
return; goto out;
states++; /* Total number of states is highest state + 1 */ states++; /* Total number of states is highest state + 1 */
...@@ -828,7 +829,7 @@ static void cooling_device_stats_setup(struct thermal_cooling_device *cdev) ...@@ -828,7 +829,7 @@ static void cooling_device_stats_setup(struct thermal_cooling_device *cdev)
stats = kzalloc(var, GFP_KERNEL); stats = kzalloc(var, GFP_KERNEL);
if (!stats) if (!stats)
return; goto out;
stats->time_in_state = (ktime_t *)(stats + 1); stats->time_in_state = (ktime_t *)(stats + 1);
stats->trans_table = (unsigned int *)(stats->time_in_state + states); stats->trans_table = (unsigned int *)(stats->time_in_state + states);
...@@ -838,9 +839,12 @@ static void cooling_device_stats_setup(struct thermal_cooling_device *cdev) ...@@ -838,9 +839,12 @@ static void cooling_device_stats_setup(struct thermal_cooling_device *cdev)
spin_lock_init(&stats->lock); spin_lock_init(&stats->lock);
stats_attr_group = &cooling_device_stats_attr_group;
out:
/* Fill the empty slot left in cooling_device_attr_groups */ /* Fill the empty slot left in cooling_device_attr_groups */
var = ARRAY_SIZE(cooling_device_attr_groups) - 2; var = ARRAY_SIZE(cooling_device_attr_groups) - 2;
cooling_device_attr_groups[var] = &cooling_device_stats_attr_group; cooling_device_attr_groups[var] = stats_attr_group;
} }
static void cooling_device_stats_destroy(struct thermal_cooling_device *cdev) static void cooling_device_stats_destroy(struct thermal_cooling_device *cdev)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment