summaryrefslogtreecommitdiffstats
path: root/drivers/thermal
diff options
context:
space:
mode:
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>2024-10-04 21:23:10 +0200
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2024-10-22 12:07:15 +0200
commitd07700b474d38ea4b1130e37d28379fc202054fa (patch)
tree4313da14e6a396df98e1d014ac451a37d3e9610f /drivers/thermal
parentthermal: core: Fix race between zone registration and system suspend (diff)
downloadlinux-d07700b474d38ea4b1130e37d28379fc202054fa.tar.xz
linux-d07700b474d38ea4b1130e37d28379fc202054fa.zip
thermal: core: Consolidate thermal zone locking during initialization
The part of thermal zone initialization carried out under thermal_list_lock acquires the thermal zone lock and releases it multiple times back and forth which is not really necessary. Instead of doing this, make it acquire the thermal zone lock once after acquiring thermal_list_lock and release it along with that lock. For this purpose, move all of the code in question to thermal_zone_init_complete() introduced previously and provide an "unlocked" variant of thermal_zone_cdev_bind() to be invoked from there. Also notice that a thermal zone does not need to be added to thermal_tz_list under its own lock, so make the new code acquire the thermal zone lock after adding it to the list. No intentional functional impact. Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Link: https://patch.msgid.link/1920382.CQOukoFCf9@rjwysocki.net Reviewed-by: Lukasz Luba <lukasz.luba@arm.com> [ rjw: Rebase on top of recent thermal core changes ] Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'drivers/thermal')
-rw-r--r--drivers/thermal/thermal_core.c39
1 files changed, 22 insertions, 17 deletions
diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c
index d1f5c165c561..5ae20a740a50 100644
--- a/drivers/thermal/thermal_core.c
+++ b/drivers/thermal/thermal_core.c
@@ -935,16 +935,14 @@ void print_bind_err_msg(struct thermal_zone_device *tz,
cdev->type, thermal_zone_trip_id(tz, trip), ret);
}
-static void thermal_zone_cdev_bind(struct thermal_zone_device *tz,
- struct thermal_cooling_device *cdev)
+static void __thermal_zone_cdev_bind(struct thermal_zone_device *tz,
+ struct thermal_cooling_device *cdev)
{
struct thermal_trip_desc *td;
if (!tz->ops.should_bind)
return;
- mutex_lock(&tz->lock);
-
for_each_trip_desc(tz, td) {
struct thermal_trip *trip = &td->trip;
struct cooling_spec c = {
@@ -961,6 +959,14 @@ static void thermal_zone_cdev_bind(struct thermal_zone_device *tz,
if (ret)
print_bind_err_msg(tz, trip, cdev, ret);
}
+}
+
+static void thermal_zone_cdev_bind(struct thermal_zone_device *tz,
+ struct thermal_cooling_device *cdev)
+{
+ mutex_lock(&tz->lock);
+
+ __thermal_zone_cdev_bind(tz, cdev);
mutex_unlock(&tz->lock);
}
@@ -1338,8 +1344,18 @@ EXPORT_SYMBOL_GPL(thermal_zone_get_crit_temp);
static void thermal_zone_init_complete(struct thermal_zone_device *tz)
{
+ struct thermal_cooling_device *cdev;
+
+ mutex_lock(&thermal_list_lock);
+
+ list_add_tail(&tz->node, &thermal_tz_list);
+
mutex_lock(&tz->lock);
+ /* Bind cooling devices for this zone. */
+ list_for_each_entry(cdev, &thermal_cdev_list, node)
+ __thermal_zone_cdev_bind(tz, cdev);
+
tz->state &= ~TZ_STATE_FLAG_INIT;
/*
* If system suspend or resume is in progress at this point, the
@@ -1352,6 +1368,8 @@ static void thermal_zone_init_complete(struct thermal_zone_device *tz)
__thermal_zone_device_update(tz, THERMAL_EVENT_UNSPECIFIED);
mutex_unlock(&tz->lock);
+
+ mutex_unlock(&thermal_list_lock);
}
/**
@@ -1388,7 +1406,6 @@ thermal_zone_device_register_with_trips(const char *type,
unsigned int polling_delay)
{
const struct thermal_trip *trip = trips;
- struct thermal_cooling_device *cdev;
struct thermal_zone_device *tz;
struct thermal_trip_desc *td;
int id;
@@ -1520,20 +1537,8 @@ thermal_zone_device_register_with_trips(const char *type,
if (result)
goto remove_hwmon;
- mutex_lock(&thermal_list_lock);
-
- mutex_lock(&tz->lock);
- list_add_tail(&tz->node, &thermal_tz_list);
- mutex_unlock(&tz->lock);
-
- /* Bind cooling devices for this zone */
- list_for_each_entry(cdev, &thermal_cdev_list, node)
- thermal_zone_cdev_bind(tz, cdev);
-
thermal_zone_init_complete(tz);
- mutex_unlock(&thermal_list_lock);
-
thermal_notify_tz_create(tz);
thermal_debug_tz_add(tz);