summaryrefslogtreecommitdiff
path: root/arch/mips/mm
diff options
context:
space:
mode:
authorJames Hogan <james.hogan@imgtec.com>2016-07-13 14:12:52 +0100
committerRalf Baechle <ralf@linux-mips.org>2016-07-29 10:19:29 +0200
commit640511ae92466800c75da77a3c7f72b8488c93a1 (patch)
tree53af8725ed47b4861942dffdb412d604fa67d311 /arch/mips/mm
parent6d758bfc7b05b11a4a853c3052cb815f40b82afe (diff)
MIPS: c-r4k: Exclude sibling CPUs in SMP calls
When performing SMP calls to foreign cores, exclude sibling CPUs from the provided map, as we already handle the local core on the current CPU. This prevents an SMP call from for example core 0, VPE 1 to VPE 0 on the same core. In the process the cpu_foreign_map cpumask is turned into an array of cpumasks, so that each CPU has its own version of it which excludes sibling CPUs. r4k_op_needs_ipi() is also updated to reflect that cache management SMP calls are not needed when all CPUs are siblings (i.e. there are no foreign CPUs according to the new cpu_foreign_map[] semantics which exclude siblings). Signed-off-by: James Hogan <james.hogan@imgtec.com> Cc: Paul Burton <paul.burton@imgtec.com> Cc: Leonid Yegoshin <leonid.yegoshin@imgtec.com> Cc: Felix Fietkau <nbd@nbd.name> Cc: Jayachandran C. <jchandra@broadcom.com> Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/13801/ Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/mm')
-rw-r--r--arch/mips/mm/c-r4k.c17
1 files changed, 13 insertions, 4 deletions
diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c
index 2a4bb5057ebc..57374f0c33f2 100644
--- a/arch/mips/mm/c-r4k.c
+++ b/arch/mips/mm/c-r4k.c
@@ -56,7 +56,9 @@
* @type: Type of cache operations (R4K_HIT or R4K_INDEX).
*
* Decides whether a cache op needs to be performed on every core in the system.
- * This may change depending on the @type of cache operation.
+ * This may change depending on the @type of cache operation, as well as the set
+ * of online CPUs, so preemption should be disabled by the caller to prevent CPU
+ * hotplug from changing the result.
*
* Returns: 1 if the cache operation @type should be done on every core in
* the system.
@@ -71,9 +73,15 @@ static inline bool r4k_op_needs_ipi(unsigned int type)
/*
* Hardware doesn't globalize the required cache ops, so SMP calls may
- * be needed.
+ * be needed, but only if there are foreign CPUs (non-siblings with
+ * separate caches).
*/
- return true;
+ /* cpu_foreign_map[] undeclared when !CONFIG_SMP */
+#ifdef CONFIG_SMP
+ return !cpumask_empty(&cpu_foreign_map[0]);
+#else
+ return false;
+#endif
}
/*
@@ -90,7 +98,8 @@ static inline void r4k_on_each_cpu(unsigned int type,
{
preempt_disable();
if (r4k_op_needs_ipi(type))
- smp_call_function_many(&cpu_foreign_map, func, info, 1);
+ smp_call_function_many(&cpu_foreign_map[smp_processor_id()],
+ func, info, 1);
func(info);
preempt_enable();
}