aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon/coretemp.c
diff options
context:
space:
mode:
authorSrivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com>2014-03-10 16:41:11 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2014-03-20 08:43:47 -0400
commit3289705fe2b429569f37730ecf660719b8924420 (patch)
treeb4021a25d0da5fdebd2d87c81c5a0b1df10fb022 /drivers/hwmon/coretemp.c
parentcf0485a2ac70acb1bc83f6310a7ebef3070f0333 (diff)
hwmon, coretemp: Fix CPU hotplug callback registration
Subsystems that want to register CPU hotplug callbacks, as well as perform initialization for the CPUs that are already online, often do it as shown below: get_online_cpus(); for_each_online_cpu(cpu) init_cpu(cpu); register_cpu_notifier(&foobar_cpu_notifier); put_online_cpus(); This is wrong, since it is prone to ABBA deadlocks involving the cpu_add_remove_lock and the cpu_hotplug.lock (when running concurrently with CPU hotplug operations). Instead, the correct and race-free way of performing the callback registration is: cpu_notifier_register_begin(); for_each_online_cpu(cpu) init_cpu(cpu); /* Note the use of the double underscored version of the API */ __register_cpu_notifier(&foobar_cpu_notifier); cpu_notifier_register_done(); Fix the hwmon coretemp code by using this latter form of callback registration. Cc: Fenghua Yu <fenghua.yu@intel.com> Cc: Jean Delvare <jdelvare@suse.de> Cc: Ingo Molnar <mingo@kernel.org> Acked-by: Guenter Roeck <linux@roeck-us.net> Signed-off-by: Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'drivers/hwmon/coretemp.c')
-rw-r--r--drivers/hwmon/coretemp.c14
1 files changed, 7 insertions, 7 deletions
diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c
index bbb0b0d463f7..746a6ad8525f 100644
--- a/drivers/hwmon/coretemp.c
+++ b/drivers/hwmon/coretemp.c
@@ -849,20 +849,20 @@ static int __init coretemp_init(void)
849 if (err) 849 if (err)
850 goto exit; 850 goto exit;
851 851
852 get_online_cpus(); 852 cpu_notifier_register_begin();
853 for_each_online_cpu(i) 853 for_each_online_cpu(i)
854 get_core_online(i); 854 get_core_online(i);
855 855
856#ifndef CONFIG_HOTPLUG_CPU 856#ifndef CONFIG_HOTPLUG_CPU
857 if (list_empty(&pdev_list)) { 857 if (list_empty(&pdev_list)) {
858 put_online_cpus(); 858 cpu_notifier_register_done();
859 err = -ENODEV; 859 err = -ENODEV;
860 goto exit_driver_unreg; 860 goto exit_driver_unreg;
861 } 861 }
862#endif 862#endif
863 863
864 register_hotcpu_notifier(&coretemp_cpu_notifier); 864 __register_hotcpu_notifier(&coretemp_cpu_notifier);
865 put_online_cpus(); 865 cpu_notifier_register_done();
866 return 0; 866 return 0;
867 867
868#ifndef CONFIG_HOTPLUG_CPU 868#ifndef CONFIG_HOTPLUG_CPU
@@ -877,8 +877,8 @@ static void __exit coretemp_exit(void)
877{ 877{
878 struct pdev_entry *p, *n; 878 struct pdev_entry *p, *n;
879 879
880 get_online_cpus(); 880 cpu_notifier_register_begin();
881 unregister_hotcpu_notifier(&coretemp_cpu_notifier); 881 __unregister_hotcpu_notifier(&coretemp_cpu_notifier);
882 mutex_lock(&pdev_list_mutex); 882 mutex_lock(&pdev_list_mutex);
883 list_for_each_entry_safe(p, n, &pdev_list, list) { 883 list_for_each_entry_safe(p, n, &pdev_list, list) {
884 platform_device_unregister(p->pdev); 884 platform_device_unregister(p->pdev);
@@ -886,7 +886,7 @@ static void __exit coretemp_exit(void)
886 kfree(p); 886 kfree(p);
887 } 887 }
888 mutex_unlock(&pdev_list_mutex); 888 mutex_unlock(&pdev_list_mutex);
889 put_online_cpus(); 889 cpu_notifier_register_done();
890 platform_driver_unregister(&coretemp_driver); 890 platform_driver_unregister(&coretemp_driver);
891} 891}
892 892