Commit 640511ae authored by James Hogan's avatar James Hogan Committed by Ralf Baechle

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: default avatarJames 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: default avatarRalf Baechle <ralf@linux-mips.org>
parent 6d758bfc
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
extern int smp_num_siblings; extern int smp_num_siblings;
extern cpumask_t cpu_sibling_map[]; extern cpumask_t cpu_sibling_map[];
extern cpumask_t cpu_core_map[]; extern cpumask_t cpu_core_map[];
extern cpumask_t cpu_foreign_map; extern cpumask_t cpu_foreign_map[];
#define raw_smp_processor_id() (current_thread_info()->cpu) #define raw_smp_processor_id() (current_thread_info()->cpu)
......
...@@ -72,7 +72,7 @@ EXPORT_SYMBOL(cpu_core_map); ...@@ -72,7 +72,7 @@ EXPORT_SYMBOL(cpu_core_map);
* A logcal cpu mask containing only one VPE per core to * A logcal cpu mask containing only one VPE per core to
* reduce the number of IPIs on large MT systems. * reduce the number of IPIs on large MT systems.
*/ */
cpumask_t cpu_foreign_map __read_mostly; cpumask_t cpu_foreign_map[NR_CPUS] __read_mostly;
EXPORT_SYMBOL(cpu_foreign_map); EXPORT_SYMBOL(cpu_foreign_map);
/* representing cpus for which sibling maps can be computed */ /* representing cpus for which sibling maps can be computed */
...@@ -141,7 +141,9 @@ void calculate_cpu_foreign_map(void) ...@@ -141,7 +141,9 @@ void calculate_cpu_foreign_map(void)
cpumask_set_cpu(i, &temp_foreign_map); cpumask_set_cpu(i, &temp_foreign_map);
} }
cpumask_copy(&cpu_foreign_map, &temp_foreign_map); for_each_online_cpu(i)
cpumask_andnot(&cpu_foreign_map[i],
&temp_foreign_map, &cpu_sibling_map[i]);
} }
struct plat_smp_ops *mp_ops; struct plat_smp_ops *mp_ops;
......
...@@ -56,7 +56,9 @@ ...@@ -56,7 +56,9 @@
* @type: Type of cache operations (R4K_HIT or R4K_INDEX). * @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. * 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 * Returns: 1 if the cache operation @type should be done on every core in
* the system. * the system.
...@@ -71,9 +73,15 @@ static inline bool r4k_op_needs_ipi(unsigned int type) ...@@ -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 * 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, ...@@ -90,7 +98,8 @@ static inline void r4k_on_each_cpu(unsigned int type,
{ {
preempt_disable(); preempt_disable();
if (r4k_op_needs_ipi(type)) 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); func(info);
preempt_enable(); preempt_enable();
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment