summaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/smp.c
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt2017-04-05 09:54:49 +0200
committerMichael Ellerman2017-04-07 04:01:27 +0200
commita978e13965a40ac07163643cc3fa0ddb0d354198 (patch)
tree64f2eb659ce991062ff1a85949f14a11d1450ba3 /arch/powerpc/kernel/smp.c
parentpowerpc: Add optional smp_ops->prepare_cpu SMP callback (diff)
downloadkernel-qcow2-linux-a978e13965a40ac07163643cc3fa0ddb0d354198.tar.gz
kernel-qcow2-linux-a978e13965a40ac07163643cc3fa0ddb0d354198.tar.xz
kernel-qcow2-linux-a978e13965a40ac07163643cc3fa0ddb0d354198.zip
powerpc/smp: Remove migrate_irq() custom implementation
Some powerpc platforms use this to move IRQs away from a CPU being unplugged. This function has several bugs such as not taking the right locks or failing to NULL check pointers. There's a new generic function doing exactly the same thing without all the bugs, so let's use it instead. mpe: The obvious place for the select of GENERIC_IRQ_MIGRATION is on HOTPLUG_CPU, but that doesn't work. On some configs PM_SLEEP_SMP will select HOTPLUG_CPU even though its dependencies are not met, which means the select of GENERIC_IRQ_MIGRATION doesn't happen. That leads to the build breaking. Fix it by moving the select of GENERIC_IRQ_MIGRATION to SMP. Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Diffstat (limited to 'arch/powerpc/kernel/smp.c')
-rw-r--r--arch/powerpc/kernel/smp.c9
1 files changed, 8 insertions, 1 deletions
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
index b12f5f0a408f..6e61cdb89194 100644
--- a/arch/powerpc/kernel/smp.c
+++ b/arch/powerpc/kernel/smp.c
@@ -439,7 +439,14 @@ int generic_cpu_disable(void)
#ifdef CONFIG_PPC64
vdso_data->processorCount--;
#endif
- migrate_irqs();
+ /* Update affinity of all IRQs previously aimed at this CPU */
+ irq_migrate_all_off_this_cpu();
+
+ /* Give the CPU time to drain in-flight ones */
+ local_irq_enable();
+ mdelay(1);
+ local_irq_disable();
+
return 0;
}