aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base
diff options
context:
space:
mode:
authorSrivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com>2014-03-10 16:40:12 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2014-03-20 08:43:45 -0400
commite12b711196a158a475350ee67876a1e9e2601661 (patch)
tree74b2750036eb346ebb24989d5ac4e28ae9e12b55 /drivers/base
parent0197fbd212461f25666272b9e4654f2ccd94cff8 (diff)
drivers/base/topology.c: 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 topology code by using this latter form of callback registration. Cc: Ingo Molnar <mingo@kernel.org> Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.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 'drivers/base')
-rw-r--r--drivers/base/topology.c12
1 files changed, 8 insertions, 4 deletions
diff --git a/drivers/base/topology.c b/drivers/base/topology.c
index 94ffee378f10..a738d1069d6b 100644
--- a/drivers/base/topology.c
+++ b/drivers/base/topology.c
@@ -161,16 +161,20 @@ static int topology_cpu_callback(struct notifier_block *nfb,
161static int topology_sysfs_init(void) 161static int topology_sysfs_init(void)
162{ 162{
163 int cpu; 163 int cpu;
164 int rc; 164 int rc = 0;
165
166 cpu_notifier_register_begin();
165 167
166 for_each_online_cpu(cpu) { 168 for_each_online_cpu(cpu) {
167 rc = topology_add_dev(cpu); 169 rc = topology_add_dev(cpu);
168 if (rc) 170 if (rc)
169 return rc; 171 goto out;
170 } 172 }
171 hotcpu_notifier(topology_cpu_callback, 0); 173 __hotcpu_notifier(topology_cpu_callback, 0);
172 174
173 return 0; 175out:
176 cpu_notifier_register_done();
177 return rc;
174} 178}
175 179
176device_initcall(topology_sysfs_init); 180device_initcall(topology_sysfs_init);