aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatt Redfearn <matt.redfearn@imgtec.com>2016-11-04 05:28:56 -0400
committerRalf Baechle <ralf@linux-mips.org>2017-01-03 10:34:38 -0500
commita00eeede507c975087b7b8df8cf2c9f88ba285de (patch)
treed14183fcb4d0de893b0f0bf68b2c5f1e724c3180
parent9799270affc53414da96e77e454a5616b39cdab0 (diff)
MIPS: SMP: Use a completion event to signal CPU up
If a secondary CPU failed to start, for any reason, the CPU requesting the secondary to start would get stuck in the loop waiting for the secondary to be present in the cpu_callin_map. Rather than that, use a completion event to signal that the secondary CPU has started and is waiting to synchronise counters. Since the CPU presence will no longer be marked in cpu_callin_map, remove the redundant test from arch_cpu_idle_dead(). Signed-off-by: Matt Redfearn <matt.redfearn@imgtec.com> Cc: Maciej W. Rozycki <macro@imgtec.com> Cc: Jiri Slaby <jslaby@suse.cz> Cc: Paul Gortmaker <paul.gortmaker@windriver.com> Cc: Chris Metcalf <cmetcalf@mellanox.com> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Qais Yousef <qsyousef@gmail.com> Cc: James Hogan <james.hogan@imgtec.com> Cc: Paul Burton <paul.burton@imgtec.com> Cc: Marcin Nowakowski <marcin.nowakowski@imgtec.com> Cc: Andrew Morton <akpm@linux-foundation.org> Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/14502/ Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
-rw-r--r--arch/mips/kernel/process.c4
-rw-r--r--arch/mips/kernel/smp.c15
2 files changed, 10 insertions, 9 deletions
diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c
index efa1df52c616..3da0161bdf84 100644
--- a/arch/mips/kernel/process.c
+++ b/arch/mips/kernel/process.c
@@ -50,9 +50,7 @@
50#ifdef CONFIG_HOTPLUG_CPU 50#ifdef CONFIG_HOTPLUG_CPU
51void arch_cpu_idle_dead(void) 51void arch_cpu_idle_dead(void)
52{ 52{
53 /* What the heck is this check doing ? */ 53 play_dead();
54 if (!cpumask_test_cpu(smp_processor_id(), &cpu_callin_map))
55 play_dead();
56} 54}
57#endif 55#endif
58 56
diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c
index 7ebb1918e2ac..03daf9008124 100644
--- a/arch/mips/kernel/smp.c
+++ b/arch/mips/kernel/smp.c
@@ -68,6 +68,8 @@ EXPORT_SYMBOL(cpu_sibling_map);
68cpumask_t cpu_core_map[NR_CPUS] __read_mostly; 68cpumask_t cpu_core_map[NR_CPUS] __read_mostly;
69EXPORT_SYMBOL(cpu_core_map); 69EXPORT_SYMBOL(cpu_core_map);
70 70
71static DECLARE_COMPLETION(cpu_running);
72
71/* 73/*
72 * A logcal cpu mask containing only one VPE per core to 74 * A logcal cpu mask containing only one VPE per core to
73 * reduce the number of IPIs on large MT systems. 75 * reduce the number of IPIs on large MT systems.
@@ -369,7 +371,7 @@ asmlinkage void start_secondary(void)
369 cpumask_set_cpu(cpu, &cpu_coherent_mask); 371 cpumask_set_cpu(cpu, &cpu_coherent_mask);
370 notify_cpu_starting(cpu); 372 notify_cpu_starting(cpu);
371 373
372 cpumask_set_cpu(cpu, &cpu_callin_map); 374 complete(&cpu_running);
373 synchronise_count_slave(cpu); 375 synchronise_count_slave(cpu);
374 376
375 set_cpu_online(cpu, true); 377 set_cpu_online(cpu, true);
@@ -430,7 +432,6 @@ void smp_prepare_boot_cpu(void)
430{ 432{
431 set_cpu_possible(0, true); 433 set_cpu_possible(0, true);
432 set_cpu_online(0, true); 434 set_cpu_online(0, true);
433 cpumask_set_cpu(0, &cpu_callin_map);
434} 435}
435 436
436int __cpu_up(unsigned int cpu, struct task_struct *tidle) 437int __cpu_up(unsigned int cpu, struct task_struct *tidle)
@@ -438,11 +439,13 @@ int __cpu_up(unsigned int cpu, struct task_struct *tidle)
438 mp_ops->boot_secondary(cpu, tidle); 439 mp_ops->boot_secondary(cpu, tidle);
439 440
440 /* 441 /*
441 * Trust is futile. We should really have timeouts ... 442 * We must check for timeout here, as the CPU will not be marked
443 * online until the counters are synchronised.
442 */ 444 */
443 while (!cpumask_test_cpu(cpu, &cpu_callin_map)) { 445 if (!wait_for_completion_timeout(&cpu_running,
444 udelay(100); 446 msecs_to_jiffies(1000))) {
445 schedule(); 447 pr_crit("CPU%u: failed to start\n", cpu);
448 return -EIO;
446 } 449 }
447 450
448 synchronise_count_master(cpu); 451 synchronise_count_master(cpu);