diff options
Diffstat (limited to 'kernel/cpu.c')
| -rw-r--r-- | kernel/cpu.c | 25 |
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 |
| 440 | static cpumask_var_t frozen_cpus; | 452 | static cpumask_var_t frozen_cpus; |
| 441 | 453 | ||
| 442 | void __weak arch_disable_nonboot_cpus_begin(void) | ||
| 443 | { | ||
| 444 | } | ||
| 445 | |||
| 446 | void __weak arch_disable_nonboot_cpus_end(void) | ||
| 447 | { | ||
| 448 | } | ||
| 449 | |||
| 450 | int disable_nonboot_cpus(void) | 454 | int 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 */ |
