From: Silas Boyd-Wickizer Date: Wed, 8 Aug 2012 22:42:14 +0000 (+1000) Subject: hwmon: (coretemp) Use get_online_cpus to avoid races involving CPU hotplug X-Git-Tag: next-20120816~68^2 X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=4ac12236d93b961b1df821d0d5a284008b3de2af;p=karo-tx-linux.git hwmon: (coretemp) Use get_online_cpus to avoid races involving CPU hotplug coretemp_init loops with for_each_online_cpu, adding platform_devices and sysfs interfaces, then calls register_hotcpu_notifier. There is a race if a CPU is offlined or onlined after the loop, but before register_hotcpu_notifier. The race might result in the absence of a platform_device+sysfs interface for an online CPU, or the presence of a platform_device+sysfs interface for an offline CPU. A similar race occurs during coretemp_exit, after the module calls unregister_hotcpu_notifier, but before it unregisters all devices, a CPU might offline and a device for an offline CPU will exist for a short while. This fix surrounds for_each_online_cpu and register_hotcpu_notifier with get_online_cpus+put_online_cpus; and surrounds unregister_hotcpu_notifier and device unregistering with get_online_cpus+put_online_cpus. Build tested. Signed-off-by: Silas Boyd-Wickizer Signed-off-by: Jean Delvare --- diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c index faa16f80db9c..59910653d7ab 100644 --- a/drivers/hwmon/coretemp.c +++ b/drivers/hwmon/coretemp.c @@ -815,17 +815,20 @@ static int __init coretemp_init(void) if (err) goto exit; + get_online_cpus(); for_each_online_cpu(i) get_core_online(i); #ifndef CONFIG_HOTPLUG_CPU if (list_empty(&pdev_list)) { + put_online_cpus(); err = -ENODEV; goto exit_driver_unreg; } #endif register_hotcpu_notifier(&coretemp_cpu_notifier); + put_online_cpus(); return 0; #ifndef CONFIG_HOTPLUG_CPU @@ -840,6 +843,7 @@ static void __exit coretemp_exit(void) { struct pdev_entry *p, *n; + get_online_cpus(); unregister_hotcpu_notifier(&coretemp_cpu_notifier); mutex_lock(&pdev_list_mutex); list_for_each_entry_safe(p, n, &pdev_list, list) { @@ -848,6 +852,7 @@ static void __exit coretemp_exit(void) kfree(p); } mutex_unlock(&pdev_list_mutex); + put_online_cpus(); platform_driver_unregister(&coretemp_driver); }