aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/cpu.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/cpu.c')
-rw-r--r--kernel/cpu.c25
1 files changed, 13 insertions, 12 deletions
diff --git a/kernel/cpu.c b/kernel/cpu.c
index 14d32588cccd..42bd331ee0ab 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -80,6 +80,10 @@ void put_online_cpus(void)
80 if (cpu_hotplug.active_writer == current) 80 if (cpu_hotplug.active_writer == current)
81 return; 81 return;
82 mutex_lock(&cpu_hotplug.lock); 82 mutex_lock(&cpu_hotplug.lock);
83
84 if (WARN_ON(!cpu_hotplug.refcount))
85 cpu_hotplug.refcount++; /* try to fix things up */
86
83 if (!--cpu_hotplug.refcount && unlikely(cpu_hotplug.active_writer)) 87 if (!--cpu_hotplug.refcount && unlikely(cpu_hotplug.active_writer))
84 wake_up_process(cpu_hotplug.active_writer); 88 wake_up_process(cpu_hotplug.active_writer);
85 mutex_unlock(&cpu_hotplug.lock); 89 mutex_unlock(&cpu_hotplug.lock);
@@ -280,12 +284,13 @@ static int __ref _cpu_down(unsigned int cpu, int tasks_frozen)
280 __func__, cpu); 284 __func__, cpu);
281 goto out_release; 285 goto out_release;
282 } 286 }
287 smpboot_park_threads(cpu);
283 288
284 err = __stop_machine(take_cpu_down, &tcd_param, cpumask_of(cpu)); 289 err = __stop_machine(take_cpu_down, &tcd_param, cpumask_of(cpu));
285 if (err) { 290 if (err) {
286 /* CPU didn't die: tell everyone. Can't complain. */ 291 /* CPU didn't die: tell everyone. Can't complain. */
292 smpboot_unpark_threads(cpu);
287 cpu_notify_nofail(CPU_DOWN_FAILED | mod, hcpu); 293 cpu_notify_nofail(CPU_DOWN_FAILED | mod, hcpu);
288
289 goto out_release; 294 goto out_release;
290 } 295 }
291 BUG_ON(cpu_online(cpu)); 296 BUG_ON(cpu_online(cpu));
@@ -354,6 +359,10 @@ static int __cpuinit _cpu_up(unsigned int cpu, int tasks_frozen)
354 goto out; 359 goto out;
355 } 360 }
356 361
362 ret = smpboot_create_threads(cpu);
363 if (ret)
364 goto out;
365
357 ret = __cpu_notify(CPU_UP_PREPARE | mod, hcpu, -1, &nr_calls); 366 ret = __cpu_notify(CPU_UP_PREPARE | mod, hcpu, -1, &nr_calls);
358 if (ret) { 367 if (ret) {
359 nr_calls--; 368 nr_calls--;
@@ -368,6 +377,9 @@ static int __cpuinit _cpu_up(unsigned int cpu, int tasks_frozen)
368 goto out_notify; 377 goto out_notify;
369 BUG_ON(!cpu_online(cpu)); 378 BUG_ON(!cpu_online(cpu));
370 379
380 /* Wake the per cpu threads */
381 smpboot_unpark_threads(cpu);
382
371 /* Now call notifier in preparation. */ 383 /* Now call notifier in preparation. */
372 cpu_notify(CPU_ONLINE | mod, hcpu); 384 cpu_notify(CPU_ONLINE | mod, hcpu);
373 385
@@ -439,14 +451,6 @@ EXPORT_SYMBOL_GPL(cpu_up);
439#ifdef CONFIG_PM_SLEEP_SMP 451#ifdef CONFIG_PM_SLEEP_SMP
440static cpumask_var_t frozen_cpus; 452static cpumask_var_t frozen_cpus;
441 453
442void __weak arch_disable_nonboot_cpus_begin(void)
443{
444}
445
446void __weak arch_disable_nonboot_cpus_end(void)
447{
448}
449
450int disable_nonboot_cpus(void) 454int disable_nonboot_cpus(void)
451{ 455{
452 int cpu, first_cpu, error = 0; 456 int cpu, first_cpu, error = 0;
@@ -458,7 +462,6 @@ int disable_nonboot_cpus(void)
458 * with the userspace trying to use the CPU hotplug at the same time 462 * with the userspace trying to use the CPU hotplug at the same time
459 */ 463 */
460 cpumask_clear(frozen_cpus); 464 cpumask_clear(frozen_cpus);
461 arch_disable_nonboot_cpus_begin();
462 465
463 printk("Disabling non-boot CPUs ...\n"); 466 printk("Disabling non-boot CPUs ...\n");
464 for_each_online_cpu(cpu) { 467 for_each_online_cpu(cpu) {
@@ -474,8 +477,6 @@ int disable_nonboot_cpus(void)
474 } 477 }
475 } 478 }
476 479
477 arch_disable_nonboot_cpus_end();
478
479 if (!error) { 480 if (!error) {
480 BUG_ON(num_online_cpus() > 1); 481 BUG_ON(num_online_cpus() > 1);
481 /* Make sure the CPUs won't be enabled by someone else */ 482 /* Make sure the CPUs won't be enabled by someone else */