linux/drivers/thermal
Michele Di Giorgio d0b7306d20 thermal: fix race condition when updating cooling device
When multiple thermal zones are bound to the same cooling device, multiple
kernel threads may want to update the cooling device state by calling
thermal_cdev_update(). Having cdev not protected by a mutex can lead to a race
condition. Consider the following situation with two kernel threads k1 and k2:

	    Thread k1				Thread k2
                                    ||
                                    ||  call thermal_cdev_update()
                                    ||      ...
                                    ||      set_cur_state(cdev, target);
    call power_actor_set_power()    ||
        ...                         ||
        instance->target = state;   ||
        cdev->updated = false;      ||
                                    ||      cdev->updated = true;
                                    ||      // completes execution
    call thermal_cdev_update()      ||
        // cdev->updated == true    ||
        return;                     ||
                                    \/
                                    time

k2 has already looped through the thermal instances looking for the deepest
cooling device state and is preempted right before setting cdev->updated to
true. Now, k1 runs, modifies the thermal instance state and sets cdev->updated
to false. Then, k1 is preempted and k2 continues the execution by setting
cdev->updated to true, therefore preventing k1 from performing the update.
Notice that this is not an issue if k2 looks at the instance->target modified by
k1 "after" it is assigned by k1. In fact, in this case the update will happen
anyway and k1 can safely return immediately from thermal_cdev_update().

This may lead to a situation where a thermal governor never updates the cooling
device. For example, this is the case for the step_wise governor: when calling
the function thermal_zone_trip_update(), the governor may always get a new state
equal to the old one (which, however, wasn't notified to the cooling device) and
will therefore skip the update.

CC: Zhang Rui <rui.zhang@intel.com>
CC: Eduardo Valentin <edubezval@gmail.com>
CC: Peter Feuerer <peter@piie.net>
Reported-by: Toby Huang <toby.huang@arm.com>
Signed-off-by: Michele Di Giorgio <michele.digiorgio@arm.com>
Reviewed-by: Javi Merino <javi.merino@arm.com>
Signed-off-by: Zhang Rui <rui.zhang@intel.com>
2016-08-08 10:57:39 +08:00
..
int340x_thermal Merge branches 'acpica-fixes', 'acpi-video' and 'acpi-processor' 2016-06-03 22:35:05 +02:00
samsung thermal: exynos: Defer probe if vtmu is present but not registered 2016-03-08 14:22:25 -08:00
st Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/rzhang/linux 2015-09-11 16:13:47 -07:00
tegra thermal: tegra: add Tegra132 specific SOC_THERM driver 2016-05-17 07:28:31 -07:00
ti-soc-thermal thermal: convert ti-thermal to use devm_thermal_zone_of_sensor_register 2016-05-17 07:28:27 -07:00
armada_thermal.c thermal: armada: Fix possible overflow in the Armada 380 thermal sensor formula 2015-10-30 11:33:23 -07:00
clock_cooling.c thermal: introduce clock cooling device 2014-11-20 10:43:16 -04:00
cpu_cooling.c Merge back earlier cpufreq changes for v4.8. 2016-06-13 23:33:17 +02:00
db8500_cpufreq_cooling.c thermal: db8500_cpufreq_cooling: Fix module autoload for OF platform driver 2015-09-13 20:26:19 -07:00
db8500_thermal.c thermal: consistently use int for temperatures 2015-08-03 23:15:50 +08:00
devfreq_cooling.c devfreq_cooling: return on allocation failure 2015-11-04 11:06:29 -08:00
dove_thermal.c thermal: consistently use int for temperatures 2015-08-03 23:15:50 +08:00
fair_share.c thermal: fix race condition when updating cooling device 2016-08-08 10:57:39 +08:00
gov_bang_bang.c thermal: fix race condition when updating cooling device 2016-08-08 10:57:39 +08:00
hisi_thermal.c thermal: hisilicon: fix IRQ imbalance enabling 2016-05-17 07:28:30 -07:00
imx_thermal.c imx: thermal: use CPU temperature grade info for thresholds 2015-11-23 16:38:40 -08:00
intel_pch_thermal.c thermal: intel_pch_thermal: Enable Skylake PCH thermal 2016-03-15 07:51:17 +08:00
intel_powerclamp.c thermal/powerclamp: remove cpu whitelist 2016-05-08 00:07:38 +08:00
intel_quark_dts_thermal.c x86/platform/iosf_mbi: Remove duplicate definitions 2015-12-09 01:18:34 +01:00
intel_soc_dts_iosf.c x86/platform/iosf_mbi: Remove duplicate definitions 2015-12-09 01:18:34 +01:00
intel_soc_dts_iosf.h Thermal: Intel SoC: DTS thermal IOSF core 2015-05-01 11:20:42 +08:00
intel_soc_dts_thermal.c x86, thermal: Clean up and fix CPU model detection for intel_soc_dts_thermal 2016-06-08 13:03:26 +02:00
Kconfig Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/rzhang/linux 2016-05-26 09:23:43 -07:00
kirkwood_thermal.c thermal: consistently use int for temperatures 2015-08-03 23:15:50 +08:00
Makefile thermal: generic-adc: Add ADC based thermal sensor driver 2016-05-17 07:28:31 -07:00
mtk_thermal.c thermal: convert mtk_thermal to use devm_thermal_zone_of_sensor_register 2016-05-17 07:28:26 -07:00
of-thermal.c thermal: of-thermal: allow setting trip_temp on hardware 2016-05-17 07:28:28 -07:00
power_allocator.c thermal: fix race condition when updating cooling device 2016-08-08 10:57:39 +08:00
qcom-spmi-temp-alarm.c thermal: convert qcom-spmi to use devm_thermal_zone_of_sensor_register 2016-05-17 07:28:26 -07:00
rcar_thermal.c thermal: convert rcar_thermal to use devm_thermal_zone_of_sensor_register 2016-05-17 07:28:27 -07:00
rockchip_thermal.c thermal: rockchip: use the usleep_range instead of udelay 2016-05-17 07:28:33 -07:00
spear_thermal.c thermal: spear: use __maybe_unused for PM functions 2016-02-09 14:12:08 -08:00
step_wise.c thermal: fix race condition when updating cooling device 2016-08-08 10:57:39 +08:00
tango_thermal.c thermal: tango: initialize TEMPSI_CFG 2016-05-17 07:28:33 -07:00
thermal_core.c thermal: fix race condition when updating cooling device 2016-08-08 10:57:39 +08:00
thermal_core.h Thermal: initialize thermal zone device correctly 2015-12-29 15:59:44 +08:00
thermal_hwmon.c thermal: consistently use int for temperatures 2015-08-03 23:15:50 +08:00
thermal_hwmon.h thermal: hwmon: move hwmon support to single file 2013-09-03 09:09:12 -04:00
thermal-generic-adc.c thermal: generic-adc: Add ADC based thermal sensor driver 2016-05-17 07:28:31 -07:00
user_space.c Thermal: build thermal governors into thermal_sys module 2013-04-14 23:28:43 +08:00
x86_pkg_temp_thermal.c thermal: x86_pkg_temp: Handle the FROZEN hot plug notifier actions. 2016-05-17 09:59:29 +08:00