aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSrivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com>2014-03-10 16:36:31 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2014-03-20 08:43:42 -0400
commitd1a5511390b0eb242c70ab977abff28644f66a5a (patch)
treeca3582cec9483dad7df5a49848715c141e0ffab9
parent1e0b0c4c6b9241b66c6032e14962a149f852f23a (diff)
powerpc, 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 powerpc by using this latter form of callback registration. Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org> Cc: Paul Mackerras <paulus@samba.org> Cc: Olof Johansson <olof@lixom.net> Cc: Wang Dongsheng <dongsheng.wang@freescale.com> Cc: Ingo Molnar <mingo@kernel.org> Acked-by: Madhavan Srinivasan <maddy@linux.vnet.ibm.com> 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/powerpc/kernel/sysfs.c8
1 files changed, 7 insertions, 1 deletions
diff --git a/arch/powerpc/kernel/sysfs.c b/arch/powerpc/kernel/sysfs.c
index 97e1dc917683..d90d4b7810d6 100644
--- a/arch/powerpc/kernel/sysfs.c
+++ b/arch/powerpc/kernel/sysfs.c
@@ -975,7 +975,8 @@ static int __init topology_init(void)
975 int cpu; 975 int cpu;
976 976
977 register_nodes(); 977 register_nodes();
978 register_cpu_notifier(&sysfs_cpu_nb); 978
979 cpu_notifier_register_begin();
979 980
980 for_each_possible_cpu(cpu) { 981 for_each_possible_cpu(cpu) {
981 struct cpu *c = &per_cpu(cpu_devices, cpu); 982 struct cpu *c = &per_cpu(cpu_devices, cpu);
@@ -999,6 +1000,11 @@ static int __init topology_init(void)
999 if (cpu_online(cpu)) 1000 if (cpu_online(cpu))
1000 register_cpu_online(cpu); 1001 register_cpu_online(cpu);
1001 } 1002 }
1003
1004 __register_cpu_notifier(&sysfs_cpu_nb);
1005
1006 cpu_notifier_register_done();
1007
1002#ifdef CONFIG_PPC64 1008#ifdef CONFIG_PPC64
1003 sysfs_create_dscr_default(); 1009 sysfs_create_dscr_default();
1004#endif /* CONFIG_PPC64 */ 1010#endif /* CONFIG_PPC64 */