diff options
Diffstat (limited to 'arch/powerpc/kernel/smp.c')
-rw-r--r-- | arch/powerpc/kernel/smp.c | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index 8d4214afc21d..c4f420c5fc1b 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c | |||
@@ -417,6 +417,45 @@ int generic_check_cpu_restart(unsigned int cpu) | |||
417 | { | 417 | { |
418 | return per_cpu(cpu_state, cpu) == CPU_UP_PREPARE; | 418 | return per_cpu(cpu_state, cpu) == CPU_UP_PREPARE; |
419 | } | 419 | } |
420 | |||
421 | static atomic_t secondary_inhibit_count; | ||
422 | |||
423 | /* | ||
424 | * Don't allow secondary CPU threads to come online | ||
425 | */ | ||
426 | void inhibit_secondary_onlining(void) | ||
427 | { | ||
428 | /* | ||
429 | * This makes secondary_inhibit_count stable during cpu | ||
430 | * online/offline operations. | ||
431 | */ | ||
432 | get_online_cpus(); | ||
433 | |||
434 | atomic_inc(&secondary_inhibit_count); | ||
435 | put_online_cpus(); | ||
436 | } | ||
437 | EXPORT_SYMBOL_GPL(inhibit_secondary_onlining); | ||
438 | |||
439 | /* | ||
440 | * Allow secondary CPU threads to come online again | ||
441 | */ | ||
442 | void uninhibit_secondary_onlining(void) | ||
443 | { | ||
444 | get_online_cpus(); | ||
445 | atomic_dec(&secondary_inhibit_count); | ||
446 | put_online_cpus(); | ||
447 | } | ||
448 | EXPORT_SYMBOL_GPL(uninhibit_secondary_onlining); | ||
449 | |||
450 | static int secondaries_inhibited(void) | ||
451 | { | ||
452 | return atomic_read(&secondary_inhibit_count); | ||
453 | } | ||
454 | |||
455 | #else /* HOTPLUG_CPU */ | ||
456 | |||
457 | #define secondaries_inhibited() 0 | ||
458 | |||
420 | #endif | 459 | #endif |
421 | 460 | ||
422 | static void cpu_idle_thread_init(unsigned int cpu, struct task_struct *idle) | 461 | static void cpu_idle_thread_init(unsigned int cpu, struct task_struct *idle) |
@@ -435,6 +474,13 @@ int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *tidle) | |||
435 | { | 474 | { |
436 | int rc, c; | 475 | int rc, c; |
437 | 476 | ||
477 | /* | ||
478 | * Don't allow secondary threads to come online if inhibited | ||
479 | */ | ||
480 | if (threads_per_core > 1 && secondaries_inhibited() && | ||
481 | cpu % threads_per_core != 0) | ||
482 | return -EBUSY; | ||
483 | |||
438 | if (smp_ops == NULL || | 484 | if (smp_ops == NULL || |
439 | (smp_ops->cpu_bootable && !smp_ops->cpu_bootable(cpu))) | 485 | (smp_ops->cpu_bootable && !smp_ops->cpu_bootable(cpu))) |
440 | return -EINVAL; | 486 | return -EINVAL; |