summaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorJames Hogan <james.hogan@imgtec.com>2016-07-13 09:12:45 -0400
committerRalf Baechle <ralf@linux-mips.org>2016-07-29 04:19:28 -0400
commit826e99be6ab5189dbfb096389016ffb8d20a683e (patch)
tree54b8f17c570bbd47a7a71be9c5235062fdd2dd7c /arch
parenta05c392032e2bb0f6d8f8cf2dd39c36b0407db72 (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.c1
-rw-r--r--arch/mips/include/asm/smp.h2
-rw-r--r--arch/mips/kernel/smp-bmips.c1
-rw-r--r--arch/mips/kernel/smp-cps.c1
-rw-r--r--arch/mips/kernel/smp.c2
-rw-r--r--arch/mips/loongson64/loongson-3/smp.c1
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
54extern void asmlinkage smp_bootstrap(void); 54extern void asmlinkage smp_bootstrap(void);
55 55
56extern 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(&current_cpu_data), &core_cfg->vpe_mask); 398 atomic_sub(1 << cpu_vpe_id(&current_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 */
127static inline void calculate_cpu_foreign_map(void) 127void 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();