diff options
Diffstat (limited to 'kernel/cpu.c')
| -rw-r--r-- | kernel/cpu.c | 42 |
1 files changed, 35 insertions, 7 deletions
diff --git a/kernel/cpu.c b/kernel/cpu.c index cfb1d43ab801..2cc409ce0a8f 100644 --- a/kernel/cpu.c +++ b/kernel/cpu.c | |||
| @@ -64,6 +64,8 @@ void __init cpu_hotplug_init(void) | |||
| 64 | cpu_hotplug.refcount = 0; | 64 | cpu_hotplug.refcount = 0; |
| 65 | } | 65 | } |
| 66 | 66 | ||
| 67 | cpumask_t cpu_active_map; | ||
| 68 | |||
| 67 | #ifdef CONFIG_HOTPLUG_CPU | 69 | #ifdef CONFIG_HOTPLUG_CPU |
| 68 | 70 | ||
| 69 | void get_online_cpus(void) | 71 | void get_online_cpus(void) |
| @@ -291,11 +293,30 @@ int __ref cpu_down(unsigned int cpu) | |||
| 291 | int err = 0; | 293 | int err = 0; |
| 292 | 294 | ||
| 293 | cpu_maps_update_begin(); | 295 | cpu_maps_update_begin(); |
| 294 | if (cpu_hotplug_disabled) | 296 | |
| 297 | if (cpu_hotplug_disabled) { | ||
| 295 | err = -EBUSY; | 298 | err = -EBUSY; |
| 296 | else | 299 | goto out; |
| 297 | err = _cpu_down(cpu, 0); | 300 | } |
| 301 | |||
| 302 | cpu_clear(cpu, cpu_active_map); | ||
| 303 | |||
| 304 | /* | ||
| 305 | * Make sure the all cpus did the reschedule and are not | ||
| 306 | * using stale version of the cpu_active_map. | ||
| 307 | * This is not strictly necessary becuase stop_machine() | ||
| 308 | * that we run down the line already provides the required | ||
| 309 | * synchronization. But it's really a side effect and we do not | ||
| 310 | * want to depend on the innards of the stop_machine here. | ||
| 311 | */ | ||
| 312 | synchronize_sched(); | ||
| 313 | |||
| 314 | err = _cpu_down(cpu, 0); | ||
| 298 | 315 | ||
| 316 | if (cpu_online(cpu)) | ||
| 317 | cpu_set(cpu, cpu_active_map); | ||
| 318 | |||
| 319 | out: | ||
| 299 | cpu_maps_update_done(); | 320 | cpu_maps_update_done(); |
| 300 | return err; | 321 | return err; |
| 301 | } | 322 | } |
| @@ -355,11 +376,18 @@ int __cpuinit cpu_up(unsigned int cpu) | |||
| 355 | } | 376 | } |
| 356 | 377 | ||
| 357 | cpu_maps_update_begin(); | 378 | cpu_maps_update_begin(); |
| 358 | if (cpu_hotplug_disabled) | 379 | |
| 380 | if (cpu_hotplug_disabled) { | ||
| 359 | err = -EBUSY; | 381 | err = -EBUSY; |
| 360 | else | 382 | goto out; |
| 361 | err = _cpu_up(cpu, 0); | 383 | } |
| 384 | |||
| 385 | err = _cpu_up(cpu, 0); | ||
| 362 | 386 | ||
| 387 | if (cpu_online(cpu)) | ||
| 388 | cpu_set(cpu, cpu_active_map); | ||
| 389 | |||
| 390 | out: | ||
| 363 | cpu_maps_update_done(); | 391 | cpu_maps_update_done(); |
| 364 | return err; | 392 | return err; |
| 365 | } | 393 | } |
| @@ -413,7 +441,7 @@ void __ref enable_nonboot_cpus(void) | |||
| 413 | goto out; | 441 | goto out; |
| 414 | 442 | ||
| 415 | printk("Enabling non-boot CPUs ...\n"); | 443 | printk("Enabling non-boot CPUs ...\n"); |
| 416 | for_each_cpu_mask(cpu, frozen_cpus) { | 444 | for_each_cpu_mask_nr(cpu, frozen_cpus) { |
| 417 | error = _cpu_up(cpu, 1); | 445 | error = _cpu_up(cpu, 1); |
| 418 | if (!error) { | 446 | if (!error) { |
| 419 | printk("CPU%d is up\n", cpu); | 447 | printk("CPU%d is up\n", cpu); |
