aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon/via-cputemp.c
diff options
context:
space:
mode:
authorSrivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com>2014-03-10 16:41:33 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2014-03-20 08:43:48 -0400
commit2480b6a3e5e80d778455f8138ae6d6efb568cd59 (patch)
treeb649c7e80a576b58188931f8ce51949691528f0e /drivers/hwmon/via-cputemp.c
parent3289705fe2b429569f37730ecf660719b8924420 (diff)
hwmon, via-cputemp: 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 via-cputemp code by using this latter form of callback registration. 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/via-cputemp.c')
-rw-r--r--drivers/hwmon/via-cputemp.c14
1 files changed, 7 insertions, 7 deletions
diff --git a/drivers/hwmon/via-cputemp.c b/drivers/hwmon/via-cputemp.c
index 38944e94f65f..8df43c51de2c 100644
--- a/drivers/hwmon/via-cputemp.c
+++ b/drivers/hwmon/via-cputemp.c
@@ -319,7 +319,7 @@ static int __init via_cputemp_init(void)
319 if (err) 319 if (err)
320 goto exit; 320 goto exit;
321 321
322 get_online_cpus(); 322 cpu_notifier_register_begin();
323 for_each_online_cpu(i) { 323 for_each_online_cpu(i) {
324 struct cpuinfo_x86 *c = &cpu_data(i); 324 struct cpuinfo_x86 *c = &cpu_data(i);
325 325
@@ -339,14 +339,14 @@ static int __init via_cputemp_init(void)
339 339
340#ifndef CONFIG_HOTPLUG_CPU 340#ifndef CONFIG_HOTPLUG_CPU
341 if (list_empty(&pdev_list)) { 341 if (list_empty(&pdev_list)) {
342 put_online_cpus(); 342 cpu_notifier_register_done();
343 err = -ENODEV; 343 err = -ENODEV;
344 goto exit_driver_unreg; 344 goto exit_driver_unreg;
345 } 345 }
346#endif 346#endif
347 347
348 register_hotcpu_notifier(&via_cputemp_cpu_notifier); 348 __register_hotcpu_notifier(&via_cputemp_cpu_notifier);
349 put_online_cpus(); 349 cpu_notifier_register_done();
350 return 0; 350 return 0;
351 351
352#ifndef CONFIG_HOTPLUG_CPU 352#ifndef CONFIG_HOTPLUG_CPU
@@ -361,8 +361,8 @@ static void __exit via_cputemp_exit(void)
361{ 361{
362 struct pdev_entry *p, *n; 362 struct pdev_entry *p, *n;
363 363
364 get_online_cpus(); 364 cpu_notifier_register_begin();
365 unregister_hotcpu_notifier(&via_cputemp_cpu_notifier); 365 __unregister_hotcpu_notifier(&via_cputemp_cpu_notifier);
366 mutex_lock(&pdev_list_mutex); 366 mutex_lock(&pdev_list_mutex);
367 list_for_each_entry_safe(p, n, &pdev_list, list) { 367 list_for_each_entry_safe(p, n, &pdev_list, list) {
368 platform_device_unregister(p->pdev); 368 platform_device_unregister(p->pdev);
@@ -370,7 +370,7 @@ static void __exit via_cputemp_exit(void)
370 kfree(p); 370 kfree(p);
371 } 371 }
372 mutex_unlock(&pdev_list_mutex); 372 mutex_unlock(&pdev_list_mutex);
373 put_online_cpus(); 373 cpu_notifier_register_done();
374 platform_driver_unregister(&via_cputemp_driver); 374 platform_driver_unregister(&via_cputemp_driver);
375} 375}
376 376