diff options
author | Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com> | 2014-03-10 16:34:45 -0400 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2014-03-20 08:43:40 -0400 |
commit | eff722b06bdd6de326894ea2353ec0eda3e5ed34 (patch) | |
tree | 32812f5ddeaa7cf23308caaabb0131305ec96346 /arch/ia64 | |
parent | f0bdb5e0c72b7347c867da539367138ad95c6b24 (diff) |
ia64, salinfo: Fix 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 salinfo 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/salinfo.c | 6 |
1 files changed, 5 insertions, 1 deletions
diff --git a/arch/ia64/kernel/salinfo.c b/arch/ia64/kernel/salinfo.c index 960a396f5929..ee9719eebb1e 100644 --- a/arch/ia64/kernel/salinfo.c +++ b/arch/ia64/kernel/salinfo.c | |||
@@ -635,6 +635,8 @@ salinfo_init(void) | |||
635 | (void *)salinfo_entries[i].feature); | 635 | (void *)salinfo_entries[i].feature); |
636 | } | 636 | } |
637 | 637 | ||
638 | cpu_notifier_register_begin(); | ||
639 | |||
638 | for (i = 0; i < ARRAY_SIZE(salinfo_log_name); i++) { | 640 | for (i = 0; i < ARRAY_SIZE(salinfo_log_name); i++) { |
639 | data = salinfo_data + i; | 641 | data = salinfo_data + i; |
640 | data->type = i; | 642 | data->type = i; |
@@ -669,7 +671,9 @@ salinfo_init(void) | |||
669 | salinfo_timer.function = &salinfo_timeout; | 671 | salinfo_timer.function = &salinfo_timeout; |
670 | add_timer(&salinfo_timer); | 672 | add_timer(&salinfo_timer); |
671 | 673 | ||
672 | register_hotcpu_notifier(&salinfo_cpu_notifier); | 674 | __register_hotcpu_notifier(&salinfo_cpu_notifier); |
675 | |||
676 | cpu_notifier_register_done(); | ||
673 | 677 | ||
674 | return 0; | 678 | return 0; |
675 | } | 679 | } |