diff options
Diffstat (limited to 'kernel/cpu.c')
| -rw-r--r-- | kernel/cpu.c | 23 |
1 files changed, 15 insertions, 8 deletions
diff --git a/kernel/cpu.c b/kernel/cpu.c index 6ba0f1ecb212..291ac586f37f 100644 --- a/kernel/cpu.c +++ b/kernel/cpu.c | |||
| @@ -212,6 +212,8 @@ static int __ref _cpu_down(unsigned int cpu, int tasks_frozen) | |||
| 212 | err = __raw_notifier_call_chain(&cpu_chain, CPU_DOWN_PREPARE | mod, | 212 | err = __raw_notifier_call_chain(&cpu_chain, CPU_DOWN_PREPARE | mod, |
| 213 | hcpu, -1, &nr_calls); | 213 | hcpu, -1, &nr_calls); |
| 214 | if (err == NOTIFY_BAD) { | 214 | if (err == NOTIFY_BAD) { |
| 215 | set_cpu_active(cpu, true); | ||
| 216 | |||
| 215 | nr_calls--; | 217 | nr_calls--; |
| 216 | __raw_notifier_call_chain(&cpu_chain, CPU_DOWN_FAILED | mod, | 218 | __raw_notifier_call_chain(&cpu_chain, CPU_DOWN_FAILED | mod, |
| 217 | hcpu, nr_calls, NULL); | 219 | hcpu, nr_calls, NULL); |
| @@ -223,11 +225,11 @@ static int __ref _cpu_down(unsigned int cpu, int tasks_frozen) | |||
| 223 | 225 | ||
| 224 | /* Ensure that we are not runnable on dying cpu */ | 226 | /* Ensure that we are not runnable on dying cpu */ |
| 225 | cpumask_copy(old_allowed, ¤t->cpus_allowed); | 227 | cpumask_copy(old_allowed, ¤t->cpus_allowed); |
| 226 | set_cpus_allowed_ptr(current, | 228 | set_cpus_allowed_ptr(current, cpu_active_mask); |
| 227 | cpumask_of(cpumask_any_but(cpu_online_mask, cpu))); | ||
| 228 | 229 | ||
| 229 | err = __stop_machine(take_cpu_down, &tcd_param, cpumask_of(cpu)); | 230 | err = __stop_machine(take_cpu_down, &tcd_param, cpumask_of(cpu)); |
| 230 | if (err) { | 231 | if (err) { |
| 232 | set_cpu_active(cpu, true); | ||
| 231 | /* CPU didn't die: tell everyone. Can't complain. */ | 233 | /* CPU didn't die: tell everyone. Can't complain. */ |
| 232 | if (raw_notifier_call_chain(&cpu_chain, CPU_DOWN_FAILED | mod, | 234 | if (raw_notifier_call_chain(&cpu_chain, CPU_DOWN_FAILED | mod, |
| 233 | hcpu) == NOTIFY_BAD) | 235 | hcpu) == NOTIFY_BAD) |
| @@ -292,9 +294,6 @@ int __ref cpu_down(unsigned int cpu) | |||
| 292 | 294 | ||
| 293 | err = _cpu_down(cpu, 0); | 295 | err = _cpu_down(cpu, 0); |
| 294 | 296 | ||
| 295 | if (cpu_online(cpu)) | ||
| 296 | set_cpu_active(cpu, true); | ||
| 297 | |||
| 298 | out: | 297 | out: |
| 299 | cpu_maps_update_done(); | 298 | cpu_maps_update_done(); |
| 300 | stop_machine_destroy(); | 299 | stop_machine_destroy(); |
| @@ -387,15 +386,23 @@ int disable_nonboot_cpus(void) | |||
| 387 | * with the userspace trying to use the CPU hotplug at the same time | 386 | * with the userspace trying to use the CPU hotplug at the same time |
| 388 | */ | 387 | */ |
| 389 | cpumask_clear(frozen_cpus); | 388 | cpumask_clear(frozen_cpus); |
| 389 | |||
| 390 | for_each_online_cpu(cpu) { | ||
| 391 | if (cpu == first_cpu) | ||
| 392 | continue; | ||
| 393 | set_cpu_active(cpu, false); | ||
| 394 | } | ||
| 395 | |||
| 396 | synchronize_sched(); | ||
| 397 | |||
| 390 | printk("Disabling non-boot CPUs ...\n"); | 398 | printk("Disabling non-boot CPUs ...\n"); |
| 391 | for_each_online_cpu(cpu) { | 399 | for_each_online_cpu(cpu) { |
| 392 | if (cpu == first_cpu) | 400 | if (cpu == first_cpu) |
| 393 | continue; | 401 | continue; |
| 394 | error = _cpu_down(cpu, 1); | 402 | error = _cpu_down(cpu, 1); |
| 395 | if (!error) { | 403 | if (!error) |
| 396 | cpumask_set_cpu(cpu, frozen_cpus); | 404 | cpumask_set_cpu(cpu, frozen_cpus); |
| 397 | printk("CPU%d is down\n", cpu); | 405 | else { |
| 398 | } else { | ||
| 399 | printk(KERN_ERR "Error taking CPU%d down: %d\n", | 406 | printk(KERN_ERR "Error taking CPU%d down: %d\n", |
| 400 | cpu, error); | 407 | cpu, error); |
| 401 | break; | 408 | break; |
