summaryrefslogtreecommitdiffstats
path: root/drivers/thermal
diff options
context:
space:
mode:
authorDaniel Lezcano <daniel.lezcano@linaro.org>2024-10-24 12:23:03 +0200
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2024-10-24 15:00:18 +0200
commit54219ee4eaeb356e0c8e0a6609dc6b5c21e2170a (patch)
tree7299c06813f5808904f004b1925b3551d77f1582 /drivers/thermal
parent41b89dba7c5dd0a071c52aa2f8c87c507e30dfbe (diff)
downloadlinux-54219ee4eaeb356e0c8e0a6609dc6b5c21e2170a.tar.gz
linux-54219ee4eaeb356e0c8e0a6609dc6b5c21e2170a.tar.bz2
linux-54219ee4eaeb356e0c8e0a6609dc6b5c21e2170a.zip
thermal: thresholds: Fix thermal lock annotation issue
When the thermal zone is unregistered (thermal sensor module being unloaded), no lock is held when flushing the thresholds. That results in a WARN when the lockdep validation is set in the kernel config. This has been reported by syzbot. As the thermal zone is in the process of being destroyed, there is no need to send a notification about purging the thresholds to the userspace as this one will receive a thermal zone deletion notification which imply the deletion of all the associated resources like the trip points or the user thresholds. Split the function thermal_thresholds_flush() into a lockless one without notification and its call with the lock annotation followed with the thresholds flushing notification. Please note this scenario is unlikely to happen, as the sensor drivers are usually compiled-in in order to have the thermal framework to be able to kick in at boot time if needed. Fixes: 445936f9e258 ("thermal: core: Add user thresholds support") Link: https://lore.kernel.org/all/67124175.050a0220.10f4f4.0012.GAE@google.com Reported-by: syzbot+f24dd060c1911fe54c85@syzkaller.appspotmail.com Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org> Link: https://patch.msgid.link/20241024102303.1086147-1-daniel.lezcano@linaro.org [ rjw: Subject edit, added Fixes tag ] Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'drivers/thermal')
-rw-r--r--drivers/thermal/thermal_thresholds.c13
1 files changed, 9 insertions, 4 deletions
diff --git a/drivers/thermal/thermal_thresholds.c b/drivers/thermal/thermal_thresholds.c
index 9b063199a789..d9b2a0bb44fc 100644
--- a/drivers/thermal/thermal_thresholds.c
+++ b/drivers/thermal/thermal_thresholds.c
@@ -20,17 +20,22 @@ int thermal_thresholds_init(struct thermal_zone_device *tz)
return 0;
}
-void thermal_thresholds_flush(struct thermal_zone_device *tz)
+static void __thermal_thresholds_flush(struct thermal_zone_device *tz)
{
struct list_head *thresholds = &tz->user_thresholds;
struct user_threshold *entry, *tmp;
- lockdep_assert_held(&tz->lock);
-
list_for_each_entry_safe(entry, tmp, thresholds, list_node) {
list_del(&entry->list_node);
kfree(entry);
}
+}
+
+void thermal_thresholds_flush(struct thermal_zone_device *tz)
+{
+ lockdep_assert_held(&tz->lock);
+
+ __thermal_thresholds_flush(tz);
thermal_notify_threshold_flush(tz);
@@ -39,7 +44,7 @@ void thermal_thresholds_flush(struct thermal_zone_device *tz)
void thermal_thresholds_exit(struct thermal_zone_device *tz)
{
- thermal_thresholds_flush(tz);
+ __thermal_thresholds_flush(tz);
}
static int __thermal_thresholds_cmp(void *data,