aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ia64
diff options
context:
space:
mode:
authorSrivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com>2014-03-10 16:35:10 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2014-03-20 08:43:41 -0400
commitf2e48a89053dea259d7f96cf0fd1cfc7c4b34d80 (patch)
tree1dd984a6502039c5ffe6e0e863a0c31ec98af9ee /arch/ia64
parentf5a7d445ffb6b251dc41942ffe41f515e8d639a4 (diff)
ia64, err-inject: 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 error injection code in ia64 by using this latter form of callback registration. Cc: Tony Luck <tony.luck@intel.com> Cc: Fenghua Yu <fenghua.yu@intel.com> Cc: Ingo Molnar <mingo@kernel.org> 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 'arch/ia64')
-rw-r--r--arch/ia64/kernel/err_inject.c15
1 files changed, 13 insertions, 2 deletions
diff --git a/arch/ia64/kernel/err_inject.c b/arch/ia64/kernel/err_inject.c
index f59c0b844e88..0c161ed6d18e 100644
--- a/arch/ia64/kernel/err_inject.c
+++ b/arch/ia64/kernel/err_inject.c
@@ -269,12 +269,17 @@ err_inject_init(void)
269#ifdef ERR_INJ_DEBUG 269#ifdef ERR_INJ_DEBUG
270 printk(KERN_INFO "Enter error injection driver.\n"); 270 printk(KERN_INFO "Enter error injection driver.\n");
271#endif 271#endif
272
273 cpu_notifier_register_begin();
274
272 for_each_online_cpu(i) { 275 for_each_online_cpu(i) {
273 err_inject_cpu_callback(&err_inject_cpu_notifier, CPU_ONLINE, 276 err_inject_cpu_callback(&err_inject_cpu_notifier, CPU_ONLINE,
274 (void *)(long)i); 277 (void *)(long)i);
275 } 278 }
276 279
277 register_hotcpu_notifier(&err_inject_cpu_notifier); 280 __register_hotcpu_notifier(&err_inject_cpu_notifier);
281
282 cpu_notifier_register_done();
278 283
279 return 0; 284 return 0;
280} 285}
@@ -288,11 +293,17 @@ err_inject_exit(void)
288#ifdef ERR_INJ_DEBUG 293#ifdef ERR_INJ_DEBUG
289 printk(KERN_INFO "Exit error injection driver.\n"); 294 printk(KERN_INFO "Exit error injection driver.\n");
290#endif 295#endif
296
297 cpu_notifier_register_begin();
298
291 for_each_online_cpu(i) { 299 for_each_online_cpu(i) {
292 sys_dev = get_cpu_device(i); 300 sys_dev = get_cpu_device(i);
293 sysfs_remove_group(&sys_dev->kobj, &err_inject_attr_group); 301 sysfs_remove_group(&sys_dev->kobj, &err_inject_attr_group);
294 } 302 }
295 unregister_hotcpu_notifier(&err_inject_cpu_notifier); 303
304 __unregister_hotcpu_notifier(&err_inject_cpu_notifier);
305
306 cpu_notifier_register_done();
296} 307}
297 308
298module_init(err_inject_init); 309module_init(err_inject_init);