summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSrivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com>2014-03-11 00:36:09 +0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2014-03-20 16:43:41 +0400
commit1e0b0c4c6b9241b66c6032e14962a149f852f23a (patch)
tree853d28f3239cc68ac038924b6a3a8a835ac7c33f
parentf4edbcd5d1f350b90583c8f3e0e7112b28f65e62 (diff)
downloadlinux-1e0b0c4c6b9241b66c6032e14962a149f852f23a.tar.xz
sparc, sysfs: 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 sysfs code in sparc by using this latter form of callback registration. Cc: Ingo Molnar <mingo@kernel.org> Acked-by: David S. Miller <davem@davemloft.net> Signed-off-by: Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-rw-r--r--arch/sparc/kernel/sysfs.c6
1 files changed, 5 insertions, 1 deletions
diff --git a/arch/sparc/kernel/sysfs.c b/arch/sparc/kernel/sysfs.c
index c21c673e5f7c..a364000ca1aa 100644
--- a/arch/sparc/kernel/sysfs.c
+++ b/arch/sparc/kernel/sysfs.c
@@ -300,7 +300,7 @@ static int __init topology_init(void)
check_mmu_stats();
- register_cpu_notifier(&sysfs_cpu_nb);
+ cpu_notifier_register_begin();
for_each_possible_cpu(cpu) {
struct cpu *c = &per_cpu(cpu_devices, cpu);
@@ -310,6 +310,10 @@ static int __init topology_init(void)
register_cpu_online(cpu);
}
+ __register_cpu_notifier(&sysfs_cpu_nb);
+
+ cpu_notifier_register_done();
+
return 0;
}