diff options
author | James Hogan <james.hogan@imgtec.com> | 2016-07-13 09:12:45 -0400 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2016-07-29 04:19:28 -0400 |
commit | 826e99be6ab5189dbfb096389016ffb8d20a683e (patch) | |
tree | 54b8f17c570bbd47a7a71be9c5235062fdd2dd7c /arch | |
parent | a05c392032e2bb0f6d8f8cf2dd39c36b0407db72 (diff) |
MIPS: SMP: Update cpu_foreign_map on CPU disable
When a CPU is disabled via CPU hotplug, cpu_foreign_map is not updated.
This could result in cache management SMP calls being sent to offline
CPUs instead of online siblings in the same core.
Add a call to calculate_cpu_foreign_map() in the various MIPS cpu
disable callbacks after set_cpu_online(). All cases are updated for
consistency and to keep cpu_foreign_map strictly up to date, not just
those which may support hardware multithreading.
Fixes: cccf34e9411c ("MIPS: c-r4k: Fix cache flushing for MT cores")
Signed-off-by: James Hogan <james.hogan@imgtec.com>
Cc: Paul Burton <paul.burton@imgtec.com>
Cc: David Daney <david.daney@cavium.com>
Cc: Kevin Cernekee <cernekee@gmail.com>
Cc: Florian Fainelli <f.fainelli@gmail.com>
Cc: Huacai Chen <chenhc@lemote.com>
Cc: Hongliang Tao <taohl@lemote.com>
Cc: Hua Yan <yanh@lemote.com>
Cc: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/13799/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/mips/cavium-octeon/smp.c | 1 | ||||
-rw-r--r-- | arch/mips/include/asm/smp.h | 2 | ||||
-rw-r--r-- | arch/mips/kernel/smp-bmips.c | 1 | ||||
-rw-r--r-- | arch/mips/kernel/smp-cps.c | 1 | ||||
-rw-r--r-- | arch/mips/kernel/smp.c | 2 | ||||
-rw-r--r-- | arch/mips/loongson64/loongson-3/smp.c | 1 |
6 files changed, 7 insertions, 1 deletions
diff --git a/arch/mips/cavium-octeon/smp.c b/arch/mips/cavium-octeon/smp.c index 33aab89259f3..4d457d602d3b 100644 --- a/arch/mips/cavium-octeon/smp.c +++ b/arch/mips/cavium-octeon/smp.c | |||
@@ -271,6 +271,7 @@ static int octeon_cpu_disable(void) | |||
271 | return -ENOTSUPP; | 271 | return -ENOTSUPP; |
272 | 272 | ||
273 | set_cpu_online(cpu, false); | 273 | set_cpu_online(cpu, false); |
274 | calculate_cpu_foreign_map(); | ||
274 | cpumask_clear_cpu(cpu, &cpu_callin_map); | 275 | cpumask_clear_cpu(cpu, &cpu_callin_map); |
275 | octeon_fixup_irqs(); | 276 | octeon_fixup_irqs(); |
276 | 277 | ||
diff --git a/arch/mips/include/asm/smp.h b/arch/mips/include/asm/smp.h index 03722d4326a1..0c534a03bb36 100644 --- a/arch/mips/include/asm/smp.h +++ b/arch/mips/include/asm/smp.h | |||
@@ -53,6 +53,8 @@ extern cpumask_t cpu_coherent_mask; | |||
53 | 53 | ||
54 | extern void asmlinkage smp_bootstrap(void); | 54 | extern void asmlinkage smp_bootstrap(void); |
55 | 55 | ||
56 | extern void calculate_cpu_foreign_map(void); | ||
57 | |||
56 | /* | 58 | /* |
57 | * this function sends a 'reschedule' IPI to another CPU. | 59 | * this function sends a 'reschedule' IPI to another CPU. |
58 | * it goes straight through and wastes no time serializing | 60 | * it goes straight through and wastes no time serializing |
diff --git a/arch/mips/kernel/smp-bmips.c b/arch/mips/kernel/smp-bmips.c index e02addc0307f..6d0f1321e084 100644 --- a/arch/mips/kernel/smp-bmips.c +++ b/arch/mips/kernel/smp-bmips.c | |||
@@ -363,6 +363,7 @@ static int bmips_cpu_disable(void) | |||
363 | pr_info("SMP: CPU%d is offline\n", cpu); | 363 | pr_info("SMP: CPU%d is offline\n", cpu); |
364 | 364 | ||
365 | set_cpu_online(cpu, false); | 365 | set_cpu_online(cpu, false); |
366 | calculate_cpu_foreign_map(); | ||
366 | cpumask_clear_cpu(cpu, &cpu_callin_map); | 367 | cpumask_clear_cpu(cpu, &cpu_callin_map); |
367 | clear_c0_status(IE_IRQ5); | 368 | clear_c0_status(IE_IRQ5); |
368 | 369 | ||
diff --git a/arch/mips/kernel/smp-cps.c b/arch/mips/kernel/smp-cps.c index 234e7e781a94..39ba5b14802f 100644 --- a/arch/mips/kernel/smp-cps.c +++ b/arch/mips/kernel/smp-cps.c | |||
@@ -398,6 +398,7 @@ static int cps_cpu_disable(void) | |||
398 | atomic_sub(1 << cpu_vpe_id(¤t_cpu_data), &core_cfg->vpe_mask); | 398 | atomic_sub(1 << cpu_vpe_id(¤t_cpu_data), &core_cfg->vpe_mask); |
399 | smp_mb__after_atomic(); | 399 | smp_mb__after_atomic(); |
400 | set_cpu_online(cpu, false); | 400 | set_cpu_online(cpu, false); |
401 | calculate_cpu_foreign_map(); | ||
401 | cpumask_clear_cpu(cpu, &cpu_callin_map); | 402 | cpumask_clear_cpu(cpu, &cpu_callin_map); |
402 | 403 | ||
403 | return 0; | 404 | return 0; |
diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c index 0c98b4a313be..a4d4309ecff2 100644 --- a/arch/mips/kernel/smp.c +++ b/arch/mips/kernel/smp.c | |||
@@ -124,7 +124,7 @@ static inline void set_cpu_core_map(int cpu) | |||
124 | * Calculate a new cpu_foreign_map mask whenever a | 124 | * Calculate a new cpu_foreign_map mask whenever a |
125 | * new cpu appears or disappears. | 125 | * new cpu appears or disappears. |
126 | */ | 126 | */ |
127 | static inline void calculate_cpu_foreign_map(void) | 127 | void calculate_cpu_foreign_map(void) |
128 | { | 128 | { |
129 | int i, k, core_present; | 129 | int i, k, core_present; |
130 | cpumask_t temp_foreign_map; | 130 | cpumask_t temp_foreign_map; |
diff --git a/arch/mips/loongson64/loongson-3/smp.c b/arch/mips/loongson64/loongson-3/smp.c index e59759af63d9..2fec6f753a35 100644 --- a/arch/mips/loongson64/loongson-3/smp.c +++ b/arch/mips/loongson64/loongson-3/smp.c | |||
@@ -417,6 +417,7 @@ static int loongson3_cpu_disable(void) | |||
417 | return -EBUSY; | 417 | return -EBUSY; |
418 | 418 | ||
419 | set_cpu_online(cpu, false); | 419 | set_cpu_online(cpu, false); |
420 | calculate_cpu_foreign_map(); | ||
420 | cpumask_clear_cpu(cpu, &cpu_callin_map); | 421 | cpumask_clear_cpu(cpu, &cpu_callin_map); |
421 | local_irq_save(flags); | 422 | local_irq_save(flags); |
422 | fixup_irqs(); | 423 | fixup_irqs(); |