diff options
Diffstat (limited to 'arch/mips')
-rw-r--r-- | arch/mips/include/asm/smp.h | 2 | ||||
-rw-r--r-- | arch/mips/kernel/smp.c | 6 | ||||
-rw-r--r-- | arch/mips/mm/c-r4k.c | 17 |
3 files changed, 18 insertions, 7 deletions
diff --git a/arch/mips/include/asm/smp.h b/arch/mips/include/asm/smp.h index 0c534a03bb36..8bc6c70a4030 100644 --- a/arch/mips/include/asm/smp.h +++ b/arch/mips/include/asm/smp.h @@ -23,7 +23,7 @@ extern int smp_num_siblings; extern cpumask_t cpu_sibling_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) diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c index 783d5f50ab9d..f95f094f36e4 100644 --- a/arch/mips/kernel/smp.c +++ b/arch/mips/kernel/smp.c @@ -72,7 +72,7 @@ EXPORT_SYMBOL(cpu_core_map); * A logcal cpu mask containing only one VPE per core to * 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); /* representing cpus for which sibling maps can be computed */ @@ -141,7 +141,9 @@ void calculate_cpu_foreign_map(void) 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; 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(); } |