Patch "thermal: core: Rework thermal zone availability check" has been added to the 6.6-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    thermal: core: Rework thermal zone availability check

to the 6.6-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     thermal-core-rework-thermal-zone-availability-check.patch
and it can be found in the queue-6.6 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit 05caa50b4d3148008633699147da42f5450dd531
Author: Rafael J. Wysocki <rafael.j.wysocki@xxxxxxxxx>
Date:   Fri Dec 8 20:20:00 2023 +0100

    thermal: core: Rework thermal zone availability check
    
    [ Upstream commit b38aa87f67931e23ebc32c0ca00a86dfa4688719 ]
    
    In order to avoid running __thermal_zone_device_update() for thermal
    zones going away, the thermal zone lock is held around device_del()
    in thermal_zone_device_unregister() and thermal_zone_device_update()
    passes the given thermal zone device to device_is_registered().
    This allows thermal_zone_device_update() to skip the
    __thermal_zone_device_update() if device_del() has already run for
    the thermal zone at hand.
    
    However, instead of looking at driver core internals, the thermal
    subsystem may as well rely on its own data structures for this
    purpose.  Namely, if the thermal zone is not present in
    thermal_tz_list, it can be regarded as unavailable, which in fact is
    already the case in thermal_zone_device_unregister().  Accordingly,
    the device_is_registered() check in thermal_zone_device_update() can
    be replaced with checking whether or not the node list_head in struct
    thermal_zone_device is empty, in which case it is not there in
    thermal_tz_list.
    
    To make this work, though, it is necessary to initialize tz->node
    in thermal_zone_device_register_with_trips() before registering the
    thermal zone device and it needs to be added to thermal_tz_list and
    deleted from it under its zone lock.
    
    After the above modifications, the zone lock does not need to be
    held around device_del() in thermal_zone_device_unregister() any more.
    
    Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@xxxxxxxxx>
    Reviewed-and-tested-by: Lukasz Luba <lukasz.luba@xxxxxxx>
    Acked-by: Daniel Lezcano <daniel.lezcano@xxxxxxxxxx>
    Stable-dep-of: 827a07525c09 ("thermal: core: Free tzp copy along with the thermal zone")
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c
index 5a9068e8f050d..69b89a71f44eb 100644
--- a/drivers/thermal/thermal_core.c
+++ b/drivers/thermal/thermal_core.c
@@ -487,11 +487,16 @@ int thermal_zone_device_is_enabled(struct thermal_zone_device *tz)
 	return tz->mode == THERMAL_DEVICE_ENABLED;
 }
 
+static bool thermal_zone_is_present(struct thermal_zone_device *tz)
+{
+	return !list_empty(&tz->node);
+}
+
 void thermal_zone_device_update(struct thermal_zone_device *tz,
 				enum thermal_notify_event event)
 {
 	mutex_lock(&tz->lock);
-	if (device_is_registered(&tz->device))
+	if (thermal_zone_is_present(tz))
 		__thermal_zone_device_update(tz, event);
 	mutex_unlock(&tz->lock);
 }
@@ -1292,6 +1297,7 @@ thermal_zone_device_register_with_trips(const char *type, struct thermal_trip *t
 	}
 
 	INIT_LIST_HEAD(&tz->thermal_instances);
+	INIT_LIST_HEAD(&tz->node);
 	ida_init(&tz->ida);
 	mutex_init(&tz->lock);
 	init_completion(&tz->removal);
@@ -1365,7 +1371,9 @@ thermal_zone_device_register_with_trips(const char *type, struct thermal_trip *t
 	}
 
 	mutex_lock(&thermal_list_lock);
+	mutex_lock(&tz->lock);
 	list_add_tail(&tz->node, &thermal_tz_list);
+	mutex_unlock(&tz->lock);
 	mutex_unlock(&thermal_list_lock);
 
 	/* Bind cooling devices for this zone */
@@ -1455,7 +1463,10 @@ void thermal_zone_device_unregister(struct thermal_zone_device *tz)
 		mutex_unlock(&thermal_list_lock);
 		return;
 	}
+
+	mutex_lock(&tz->lock);
 	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)
@@ -1472,9 +1483,7 @@ void thermal_zone_device_unregister(struct thermal_zone_device *tz)
 	ida_free(&thermal_tz_ida, tz->id);
 	ida_destroy(&tz->ida);
 
-	mutex_lock(&tz->lock);
 	device_del(&tz->device);
-	mutex_unlock(&tz->lock);
 
 	kfree(tz->tzp);
 




[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux