diff options
Diffstat (limited to 'arch/powerpc/kernel/smp.c')
-rw-r--r-- | arch/powerpc/kernel/smp.c | 54 |
1 files changed, 50 insertions, 4 deletions
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index 2b952b5386fd..793401e65088 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c | |||
@@ -82,7 +82,7 @@ int smt_enabled_at_boot = 1; | |||
82 | static void (*crash_ipi_function_ptr)(struct pt_regs *) = NULL; | 82 | static void (*crash_ipi_function_ptr)(struct pt_regs *) = NULL; |
83 | 83 | ||
84 | #ifdef CONFIG_PPC64 | 84 | #ifdef CONFIG_PPC64 |
85 | int __devinit smp_generic_kick_cpu(int nr) | 85 | int smp_generic_kick_cpu(int nr) |
86 | { | 86 | { |
87 | BUG_ON(nr < 0 || nr >= NR_CPUS); | 87 | BUG_ON(nr < 0 || nr >= NR_CPUS); |
88 | 88 | ||
@@ -311,7 +311,7 @@ void smp_send_stop(void) | |||
311 | 311 | ||
312 | struct thread_info *current_set[NR_CPUS]; | 312 | struct thread_info *current_set[NR_CPUS]; |
313 | 313 | ||
314 | static void __devinit smp_store_cpu_info(int id) | 314 | static void smp_store_cpu_info(int id) |
315 | { | 315 | { |
316 | per_cpu(cpu_pvr, id) = mfspr(SPRN_PVR); | 316 | per_cpu(cpu_pvr, id) = mfspr(SPRN_PVR); |
317 | #ifdef CONFIG_PPC_FSL_BOOK3E | 317 | #ifdef CONFIG_PPC_FSL_BOOK3E |
@@ -355,7 +355,7 @@ void __init smp_prepare_cpus(unsigned int max_cpus) | |||
355 | max_cpus = 1; | 355 | max_cpus = 1; |
356 | } | 356 | } |
357 | 357 | ||
358 | void __devinit smp_prepare_boot_cpu(void) | 358 | void smp_prepare_boot_cpu(void) |
359 | { | 359 | { |
360 | BUG_ON(smp_processor_id() != boot_cpuid); | 360 | BUG_ON(smp_processor_id() != boot_cpuid); |
361 | #ifdef CONFIG_PPC64 | 361 | #ifdef CONFIG_PPC64 |
@@ -427,6 +427,45 @@ int generic_check_cpu_restart(unsigned int cpu) | |||
427 | { | 427 | { |
428 | return per_cpu(cpu_state, cpu) == CPU_UP_PREPARE; | 428 | return per_cpu(cpu_state, cpu) == CPU_UP_PREPARE; |
429 | } | 429 | } |
430 | |||
431 | static atomic_t secondary_inhibit_count; | ||
432 | |||
433 | /* | ||
434 | * Don't allow secondary CPU threads to come online | ||
435 | */ | ||
436 | void inhibit_secondary_onlining(void) | ||
437 | { | ||
438 | /* | ||
439 | * This makes secondary_inhibit_count stable during cpu | ||
440 | * online/offline operations. | ||
441 | */ | ||
442 | get_online_cpus(); | ||
443 | |||
444 | atomic_inc(&secondary_inhibit_count); | ||
445 | put_online_cpus(); | ||
446 | } | ||
447 | EXPORT_SYMBOL_GPL(inhibit_secondary_onlining); | ||
448 | |||
449 | /* | ||
450 | * Allow secondary CPU threads to come online again | ||
451 | */ | ||
452 | void uninhibit_secondary_onlining(void) | ||
453 | { | ||
454 | get_online_cpus(); | ||
455 | atomic_dec(&secondary_inhibit_count); | ||
456 | put_online_cpus(); | ||
457 | } | ||
458 | EXPORT_SYMBOL_GPL(uninhibit_secondary_onlining); | ||
459 | |||
460 | static int secondaries_inhibited(void) | ||
461 | { | ||
462 | return atomic_read(&secondary_inhibit_count); | ||
463 | } | ||
464 | |||
465 | #else /* HOTPLUG_CPU */ | ||
466 | |||
467 | #define secondaries_inhibited() 0 | ||
468 | |||
430 | #endif | 469 | #endif |
431 | 470 | ||
432 | static void cpu_idle_thread_init(unsigned int cpu, struct task_struct *idle) | 471 | static void cpu_idle_thread_init(unsigned int cpu, struct task_struct *idle) |
@@ -445,6 +484,13 @@ int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *tidle) | |||
445 | { | 484 | { |
446 | int rc, c; | 485 | int rc, c; |
447 | 486 | ||
487 | /* | ||
488 | * Don't allow secondary threads to come online if inhibited | ||
489 | */ | ||
490 | if (threads_per_core > 1 && secondaries_inhibited() && | ||
491 | cpu % threads_per_core != 0) | ||
492 | return -EBUSY; | ||
493 | |||
448 | if (smp_ops == NULL || | 494 | if (smp_ops == NULL || |
449 | (smp_ops->cpu_bootable && !smp_ops->cpu_bootable(cpu))) | 495 | (smp_ops->cpu_bootable && !smp_ops->cpu_bootable(cpu))) |
450 | return -EINVAL; | 496 | return -EINVAL; |
@@ -564,7 +610,7 @@ static struct device_node *cpu_to_l2cache(int cpu) | |||
564 | } | 610 | } |
565 | 611 | ||
566 | /* Activate a secondary processor. */ | 612 | /* Activate a secondary processor. */ |
567 | void __devinit start_secondary(void *unused) | 613 | void start_secondary(void *unused) |
568 | { | 614 | { |
569 | unsigned int cpu = smp_processor_id(); | 615 | unsigned int cpu = smp_processor_id(); |
570 | struct device_node *l2_cache; | 616 | struct device_node *l2_cache; |