From: "Rafael J. Wysocki" rafael.j.wysocki@intel.com
stable inclusion from stable-v5.10.137 commit 826955eebc47826e0591b3c2d33ad80cdb46f686 category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I60PLB
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=...
--------------------------------
commit d5a8aa5d7d80d21ab6b266f1bed4194b61746199 upstream.
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: 8ea229511e06 ("thermal: Add cooling device's statistics in sysfs") Reported-by: Di Shen di.shen@unisoc.com Tested-by: Di Shen di.shen@unisoc.com Cc: 4.17+ stable@vger.kernel.org # 4.17+ Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com Reviewed-by: Wei Li liwei391@huawei.com --- drivers/thermal/thermal_sysfs.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/drivers/thermal/thermal_sysfs.c b/drivers/thermal/thermal_sysfs.c index f52708f310e0..05e9a3de80b5 100644 --- a/drivers/thermal/thermal_sysfs.c +++ b/drivers/thermal/thermal_sysfs.c @@ -893,12 +893,13 @@ static const struct attribute_group cooling_device_stats_attr_group = {
static void cooling_device_stats_setup(struct thermal_cooling_device *cdev) { + const struct attribute_group *stats_attr_group = NULL; struct cooling_dev_stats *stats; unsigned long states; int var;
if (cdev->ops->get_max_state(cdev, &states)) - return; + goto out;
states++; /* Total number of states is highest state + 1 */
@@ -908,7 +909,7 @@ static void cooling_device_stats_setup(struct thermal_cooling_device *cdev)
stats = kzalloc(var, GFP_KERNEL); if (!stats) - return; + goto out;
stats->time_in_state = (ktime_t *)(stats + 1); stats->trans_table = (unsigned int *)(stats->time_in_state + states); @@ -918,9 +919,12 @@ static void cooling_device_stats_setup(struct thermal_cooling_device *cdev)
spin_lock_init(&stats->lock);
+ stats_attr_group = &cooling_device_stats_attr_group; + +out: /* Fill the empty slot left in cooling_device_attr_groups */ 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)