aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/smp.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/kernel/smp.c')
-rw-r--r--arch/powerpc/kernel/smp.c54
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;
82static void (*crash_ipi_function_ptr)(struct pt_regs *) = NULL; 82static void (*crash_ipi_function_ptr)(struct pt_regs *) = NULL;
83 83
84#ifdef CONFIG_PPC64 84#ifdef CONFIG_PPC64
85int __devinit smp_generic_kick_cpu(int nr) 85int 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
312struct thread_info *current_set[NR_CPUS]; 312struct thread_info *current_set[NR_CPUS];
313 313
314static void __devinit smp_store_cpu_info(int id) 314static 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
358void __devinit smp_prepare_boot_cpu(void) 358void 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
431static atomic_t secondary_inhibit_count;
432
433/*
434 * Don't allow secondary CPU threads to come online
435 */
436void 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}
447EXPORT_SYMBOL_GPL(inhibit_secondary_onlining);
448
449/*
450 * Allow secondary CPU threads to come online again
451 */
452void uninhibit_secondary_onlining(void)
453{
454 get_online_cpus();
455 atomic_dec(&secondary_inhibit_count);
456 put_online_cpus();
457}
458EXPORT_SYMBOL_GPL(uninhibit_secondary_onlining);
459
460static 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
432static void cpu_idle_thread_init(unsigned int cpu, struct task_struct *idle) 471static 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. */
567void __devinit start_secondary(void *unused) 613void 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;