]>
Commit | Line | Data |
---|---|---|
1 | From 156ae4b25ce08b9c79e67c808142460d9cc62aff Mon Sep 17 00:00:00 2001 | |
2 | From: Dietmar Eggemann <dietmar.eggemann@arm.com> | |
3 | Date: Mon, 21 Jan 2019 14:42:42 +0100 | |
4 | Subject: ARM: 8824/1: fix a migrating irq bug when hotplug cpu | |
5 | ||
6 | [ Upstream commit 1b5ba350784242eb1f899bcffd95d2c7cff61e84 ] | |
7 | ||
8 | Arm TC2 fails cpu hotplug stress test. | |
9 | ||
10 | This issue was tracked down to a missing copy of the new affinity | |
11 | cpumask for the vexpress-spc interrupt into struct | |
12 | irq_common_data.affinity when the interrupt is migrated in | |
13 | migrate_one_irq(). | |
14 | ||
15 | Fix it by replacing the arm specific hotplug cpu migration with the | |
16 | generic irq code. | |
17 | ||
18 | This is the counterpart implementation to commit 217d453d473c ("arm64: | |
19 | fix a migrating irq bug when hotplug cpu"). | |
20 | ||
21 | Tested with cpu hotplug stress test on Arm TC2 (multi_v7_defconfig plus | |
22 | CONFIG_ARM_BIG_LITTLE_CPUFREQ=y and CONFIG_ARM_VEXPRESS_SPC_CPUFREQ=y). | |
23 | The vexpress-spc interrupt (irq=22) on this board is affine to CPU0. | |
24 | Its affinity cpumask now changes correctly e.g. from 0 to 1-4 when | |
25 | CPU0 is hotplugged out. | |
26 | ||
27 | Suggested-by: Marc Zyngier <marc.zyngier@arm.com> | |
28 | Signed-off-by: Dietmar Eggemann <dietmar.eggemann@arm.com> | |
29 | Acked-by: Marc Zyngier <marc.zyngier@arm.com> | |
30 | Reviewed-by: Linus Walleij <linus.walleij@linaro.org> | |
31 | Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> | |
32 | Signed-off-by: Sasha Levin <sashal@kernel.org> | |
33 | --- | |
34 | arch/arm/Kconfig | 1 + | |
35 | arch/arm/include/asm/irq.h | 1 - | |
36 | arch/arm/kernel/irq.c | 62 -------------------------------------- | |
37 | arch/arm/kernel/smp.c | 2 +- | |
38 | 4 files changed, 2 insertions(+), 64 deletions(-) | |
39 | ||
40 | diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig | |
41 | index d1346a160760..cf69aab648fb 100644 | |
42 | --- a/arch/arm/Kconfig | |
43 | +++ b/arch/arm/Kconfig | |
44 | @@ -1447,6 +1447,7 @@ config NR_CPUS | |
45 | config HOTPLUG_CPU | |
46 | bool "Support for hot-pluggable CPUs" | |
47 | depends on SMP | |
48 | + select GENERIC_IRQ_MIGRATION | |
49 | help | |
50 | Say Y here to experiment with turning CPUs off and on. CPUs | |
51 | can be controlled through /sys/devices/system/cpu. | |
52 | diff --git a/arch/arm/include/asm/irq.h b/arch/arm/include/asm/irq.h | |
53 | index b6f319606e30..2de321e89b94 100644 | |
54 | --- a/arch/arm/include/asm/irq.h | |
55 | +++ b/arch/arm/include/asm/irq.h | |
56 | @@ -25,7 +25,6 @@ | |
57 | #ifndef __ASSEMBLY__ | |
58 | struct irqaction; | |
59 | struct pt_regs; | |
60 | -extern void migrate_irqs(void); | |
61 | ||
62 | extern void asm_do_IRQ(unsigned int, struct pt_regs *); | |
63 | void handle_IRQ(unsigned int, struct pt_regs *); | |
64 | diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c | |
65 | index ece04a457486..5b07c7a31c31 100644 | |
66 | --- a/arch/arm/kernel/irq.c | |
67 | +++ b/arch/arm/kernel/irq.c | |
68 | @@ -31,7 +31,6 @@ | |
69 | #include <linux/smp.h> | |
70 | #include <linux/init.h> | |
71 | #include <linux/seq_file.h> | |
72 | -#include <linux/ratelimit.h> | |
73 | #include <linux/errno.h> | |
74 | #include <linux/list.h> | |
75 | #include <linux/kallsyms.h> | |
76 | @@ -119,64 +118,3 @@ int __init arch_probe_nr_irqs(void) | |
77 | return nr_irqs; | |
78 | } | |
79 | #endif | |
80 | - | |
81 | -#ifdef CONFIG_HOTPLUG_CPU | |
82 | -static bool migrate_one_irq(struct irq_desc *desc) | |
83 | -{ | |
84 | - struct irq_data *d = irq_desc_get_irq_data(desc); | |
85 | - const struct cpumask *affinity = irq_data_get_affinity_mask(d); | |
86 | - struct irq_chip *c; | |
87 | - bool ret = false; | |
88 | - | |
89 | - /* | |
90 | - * If this is a per-CPU interrupt, or the affinity does not | |
91 | - * include this CPU, then we have nothing to do. | |
92 | - */ | |
93 | - if (irqd_is_per_cpu(d) || !cpumask_test_cpu(smp_processor_id(), affinity)) | |
94 | - return false; | |
95 | - | |
96 | - if (cpumask_any_and(affinity, cpu_online_mask) >= nr_cpu_ids) { | |
97 | - affinity = cpu_online_mask; | |
98 | - ret = true; | |
99 | - } | |
100 | - | |
101 | - c = irq_data_get_irq_chip(d); | |
102 | - if (!c->irq_set_affinity) | |
103 | - pr_debug("IRQ%u: unable to set affinity\n", d->irq); | |
104 | - else if (c->irq_set_affinity(d, affinity, false) == IRQ_SET_MASK_OK && ret) | |
105 | - cpumask_copy(irq_data_get_affinity_mask(d), affinity); | |
106 | - | |
107 | - return ret; | |
108 | -} | |
109 | - | |
110 | -/* | |
111 | - * The current CPU has been marked offline. Migrate IRQs off this CPU. | |
112 | - * If the affinity settings do not allow other CPUs, force them onto any | |
113 | - * available CPU. | |
114 | - * | |
115 | - * Note: we must iterate over all IRQs, whether they have an attached | |
116 | - * action structure or not, as we need to get chained interrupts too. | |
117 | - */ | |
118 | -void migrate_irqs(void) | |
119 | -{ | |
120 | - unsigned int i; | |
121 | - struct irq_desc *desc; | |
122 | - unsigned long flags; | |
123 | - | |
124 | - local_irq_save(flags); | |
125 | - | |
126 | - for_each_irq_desc(i, desc) { | |
127 | - bool affinity_broken; | |
128 | - | |
129 | - raw_spin_lock(&desc->lock); | |
130 | - affinity_broken = migrate_one_irq(desc); | |
131 | - raw_spin_unlock(&desc->lock); | |
132 | - | |
133 | - if (affinity_broken) | |
134 | - pr_warn_ratelimited("IRQ%u no longer affine to CPU%u\n", | |
135 | - i, smp_processor_id()); | |
136 | - } | |
137 | - | |
138 | - local_irq_restore(flags); | |
139 | -} | |
140 | -#endif /* CONFIG_HOTPLUG_CPU */ | |
141 | diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c | |
142 | index f57333f46242..65f85737c6a2 100644 | |
143 | --- a/arch/arm/kernel/smp.c | |
144 | +++ b/arch/arm/kernel/smp.c | |
145 | @@ -254,7 +254,7 @@ int __cpu_disable(void) | |
146 | /* | |
147 | * OK - migrate IRQs away from this CPU | |
148 | */ | |
149 | - migrate_irqs(); | |
150 | + irq_migrate_all_off_this_cpu(); | |
151 | ||
152 | /* | |
153 | * Flush user cache and TLB mappings, and then remove this CPU | |
154 | -- | |
155 | 2.19.1 | |
156 |