mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2025-01-04 04:06:26 +00:00
thermal: core: Consolidate thermal zone locking in the exit path
In analogy with a previous change in the thermal zone initialization path, to avoid acquiring the thermal zone lock and releasing it multiple times back and forth unnecessarily, move all of the code running under thermal_list_lock in thermal_zone_device_unregister() into a new function called thermal_zone_exit() and make the latter acquire the thermal zone lock only once and release it along with thermal_list_lock. For this purpose, provide an "unlocked" variant of thermal_zone_cdev_unbind() to be called by thermal_zone_exit() under the thermal zone lock. No intentional functional impact. Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Link: https://patch.msgid.link/1963152.taCxCBeP46@rjwysocki.net Reviewed-by: Lukasz Luba <lukasz.luba@arm.com>
This commit is contained in:
parent
1dae3e70b4
commit
fa4f9c9679
@ -1268,15 +1268,21 @@ void thermal_cooling_device_update(struct thermal_cooling_device *cdev)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(thermal_cooling_device_update);
|
||||
|
||||
static void thermal_zone_cdev_unbind(struct thermal_zone_device *tz,
|
||||
struct thermal_cooling_device *cdev)
|
||||
static void __thermal_zone_cdev_unbind(struct thermal_zone_device *tz,
|
||||
struct thermal_cooling_device *cdev)
|
||||
{
|
||||
struct thermal_trip_desc *td;
|
||||
|
||||
mutex_lock(&tz->lock);
|
||||
|
||||
for_each_trip_desc(tz, td)
|
||||
thermal_unbind_cdev_from_trip(tz, &td->trip, cdev);
|
||||
}
|
||||
|
||||
static void thermal_zone_cdev_unbind(struct thermal_zone_device *tz,
|
||||
struct thermal_cooling_device *cdev)
|
||||
{
|
||||
mutex_lock(&tz->lock);
|
||||
|
||||
__thermal_zone_cdev_unbind(tz, cdev);
|
||||
|
||||
mutex_unlock(&tz->lock);
|
||||
}
|
||||
@ -1596,42 +1602,48 @@ struct device *thermal_zone_device(struct thermal_zone_device *tzd)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(thermal_zone_device);
|
||||
|
||||
static bool thermal_zone_exit(struct thermal_zone_device *tz)
|
||||
{
|
||||
struct thermal_cooling_device *cdev;
|
||||
bool ret = true;
|
||||
|
||||
mutex_lock(&thermal_list_lock);
|
||||
|
||||
if (list_empty(&tz->node)) {
|
||||
ret = false;
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
mutex_lock(&tz->lock);
|
||||
|
||||
tz->state |= TZ_STATE_FLAG_EXIT;
|
||||
list_del_init(&tz->node);
|
||||
|
||||
/* Unbind all cdevs associated with this thermal zone. */
|
||||
list_for_each_entry(cdev, &thermal_cdev_list, node)
|
||||
__thermal_zone_cdev_unbind(tz, cdev);
|
||||
|
||||
mutex_unlock(&tz->lock);
|
||||
|
||||
unlock:
|
||||
mutex_unlock(&thermal_list_lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* thermal_zone_device_unregister - removes the registered thermal zone device
|
||||
* @tz: the thermal zone device to remove
|
||||
*/
|
||||
void thermal_zone_device_unregister(struct thermal_zone_device *tz)
|
||||
{
|
||||
struct thermal_cooling_device *cdev;
|
||||
struct thermal_zone_device *pos = NULL;
|
||||
|
||||
if (!tz)
|
||||
return;
|
||||
|
||||
thermal_debug_tz_remove(tz);
|
||||
|
||||
mutex_lock(&thermal_list_lock);
|
||||
list_for_each_entry(pos, &thermal_tz_list, node)
|
||||
if (pos == tz)
|
||||
break;
|
||||
if (pos != tz) {
|
||||
/* thermal zone device not found */
|
||||
mutex_unlock(&thermal_list_lock);
|
||||
if (!thermal_zone_exit(tz))
|
||||
return;
|
||||
}
|
||||
|
||||
mutex_lock(&tz->lock);
|
||||
|
||||
tz->state |= TZ_STATE_FLAG_EXIT;
|
||||
list_del(&tz->node);
|
||||
|
||||
mutex_unlock(&tz->lock);
|
||||
|
||||
/* Unbind all cdevs associated with 'this' thermal zone */
|
||||
list_for_each_entry(cdev, &thermal_cdev_list, node)
|
||||
thermal_zone_cdev_unbind(tz, cdev);
|
||||
|
||||
mutex_unlock(&thermal_list_lock);
|
||||
|
||||
cancel_delayed_work_sync(&tz->poll_queue);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user