| From a00eeede507c975087b7b8df8cf2c9f88ba285de Mon Sep 17 00:00:00 2001 |
| From: Matt Redfearn <matt.redfearn@imgtec.com> |
| Date: Fri, 4 Nov 2016 09:28:56 +0000 |
| Subject: MIPS: SMP: Use a completion event to signal CPU up |
| |
| From: Matt Redfearn <matt.redfearn@imgtec.com> |
| |
| commit a00eeede507c975087b7b8df8cf2c9f88ba285de upstream. |
| |
| 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> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| arch/mips/kernel/process.c | 4 +--- |
| arch/mips/kernel/smp.c | 15 +++++++++------ |
| 2 files changed, 10 insertions(+), 9 deletions(-) |
| |
| --- a/arch/mips/kernel/process.c |
| +++ b/arch/mips/kernel/process.c |
| @@ -50,9 +50,7 @@ |
| #ifdef CONFIG_HOTPLUG_CPU |
| void arch_cpu_idle_dead(void) |
| { |
| - /* What the heck is this check doing ? */ |
| - if (!cpumask_test_cpu(smp_processor_id(), &cpu_callin_map)) |
| - play_dead(); |
| + play_dead(); |
| } |
| #endif |
| |
| --- a/arch/mips/kernel/smp.c |
| +++ b/arch/mips/kernel/smp.c |
| @@ -68,6 +68,8 @@ EXPORT_SYMBOL(cpu_sibling_map); |
| cpumask_t cpu_core_map[NR_CPUS] __read_mostly; |
| EXPORT_SYMBOL(cpu_core_map); |
| |
| +static DECLARE_COMPLETION(cpu_running); |
| + |
| /* |
| * A logcal cpu mask containing only one VPE per core to |
| * reduce the number of IPIs on large MT systems. |
| @@ -369,7 +371,7 @@ asmlinkage void start_secondary(void) |
| cpumask_set_cpu(cpu, &cpu_coherent_mask); |
| notify_cpu_starting(cpu); |
| |
| - cpumask_set_cpu(cpu, &cpu_callin_map); |
| + complete(&cpu_running); |
| synchronise_count_slave(cpu); |
| |
| set_cpu_online(cpu, true); |
| @@ -430,7 +432,6 @@ void smp_prepare_boot_cpu(void) |
| { |
| set_cpu_possible(0, true); |
| set_cpu_online(0, true); |
| - cpumask_set_cpu(0, &cpu_callin_map); |
| } |
| |
| int __cpu_up(unsigned int cpu, struct task_struct *tidle) |
| @@ -438,11 +439,13 @@ int __cpu_up(unsigned int cpu, struct ta |
| mp_ops->boot_secondary(cpu, tidle); |
| |
| /* |
| - * Trust is futile. We should really have timeouts ... |
| + * We must check for timeout here, as the CPU will not be marked |
| + * online until the counters are synchronised. |
| */ |
| - while (!cpumask_test_cpu(cpu, &cpu_callin_map)) { |
| - udelay(100); |
| - schedule(); |
| + if (!wait_for_completion_timeout(&cpu_running, |
| + msecs_to_jiffies(1000))) { |
| + pr_crit("CPU%u: failed to start\n", cpu); |
| + return -EIO; |
| } |
| |
| synchronise_count_master(cpu); |