MIPS: Unify checks for sibling CPUs
authorPaul Burton <paul.burton@imgtec.com>
Sun, 13 Aug 2017 02:49:37 +0000 (19:49 -0700)
committerRalf Baechle <ralf@linux-mips.org>
Tue, 29 Aug 2017 22:57:27 +0000 (00:57 +0200)
Up until now we have open-coded checks for whether CPUs are siblings,
with slight variations on whether we consider the package ID or not.

This will only get more complex when we introduce cluster support, so in
preparation for that this patch introduces a cpus_are_siblings()
function which can be used to check whether or not 2 CPUs are siblings
in a consistent manner.

By checking globalnumber with the VP ID masked out this also has the
neat side effect of being ready for multi-cluster systems already.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Acked-by: Rafael J. Wysocki <rjw@rjwysocki.net>
Acked-by: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/17011/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
arch/mips/include/asm/cpu-info.h
arch/mips/kernel/smp-cps.c
arch/mips/kernel/smp.c
drivers/cpuidle/cpuidle-cps.c
drivers/irqchip/irq-mips-cpu.c

index 9ae927282b121db0796c6b698703ccb141023169..0c61bdc82a53210da8be2f638a2338861a50206d 100644 (file)
@@ -158,6 +158,23 @@ static inline unsigned int cpu_vpe_id(struct cpuinfo_mips *cpuinfo)
 extern void cpu_set_core(struct cpuinfo_mips *cpuinfo, unsigned int core);
 extern void cpu_set_vpe_id(struct cpuinfo_mips *cpuinfo, unsigned int vpe);
 
+static inline bool cpus_are_siblings(int cpua, int cpub)
+{
+       struct cpuinfo_mips *infoa = &cpu_data[cpua];
+       struct cpuinfo_mips *infob = &cpu_data[cpub];
+       unsigned int gnuma, gnumb;
+
+       if (infoa->package != infob->package)
+               return false;
+
+       gnuma = infoa->globalnumber & ~MIPS_GLOBALNUMBER_VP;
+       gnumb = infob->globalnumber & ~MIPS_GLOBALNUMBER_VP;
+       if (gnuma != gnumb)
+               return false;
+
+       return true;
+}
+
 static inline unsigned long cpu_asid_inc(void)
 {
        return 1 << CONFIG_MIPS_ASID_SHIFT;
index 699459ed293b89811313c676738017d631ea6c4d..8cc5088094669a9f110e9734f677eafadc89eab9 100644 (file)
@@ -147,7 +147,7 @@ static void __init cps_prepare_cpus(unsigned int max_cpus)
                        cpu_has_dc_aliases ? "dcache aliasing" : "");
 
                for_each_present_cpu(c) {
-                       if (cpu_core(&cpu_data[c]))
+                       if (!cpus_are_siblings(smp_processor_id(), c))
                                set_cpu_present(c, false);
                }
        }
@@ -319,10 +319,10 @@ static void cps_boot_secondary(int cpu, struct task_struct *idle)
                mips_cm_unlock_other();
        }
 
-       if (core != cpu_core(&current_cpu_data)) {
+       if (!cpus_are_siblings(cpu, smp_processor_id())) {
                /* Boot a VPE on another powered up core */
                for (remote = 0; remote < NR_CPUS; remote++) {
-                       if (cpu_core(&cpu_data[remote]) != core)
+                       if (!cpus_are_siblings(cpu, remote))
                                continue;
                        if (cpu_online(remote))
                                break;
@@ -431,7 +431,7 @@ void play_dead(void)
 
                /* Look for another online VPE within the core */
                for_each_online_cpu(cpu_death_sibling) {
-                       if (cpu_core(&cpu_data[cpu_death_sibling]) != core)
+                       if (!cpus_are_siblings(cpu, cpu_death_sibling))
                                continue;
 
                        /*
index a54e5857c227e1e0cb98ec7f5bc1be9ca565b5a8..4cc43892b959a8a660398266482f44b8a695e83a 100644 (file)
@@ -96,8 +96,7 @@ static inline void set_cpu_sibling_map(int cpu)
 
        if (smp_num_siblings > 1) {
                for_each_cpu(i, &cpu_sibling_setup_map) {
-                       if (cpu_data[cpu].package == cpu_data[i].package &&
-                           cpu_core(&cpu_data[cpu]) == cpu_core(&cpu_data[i])) {
+                       if (cpus_are_siblings(cpu, i)) {
                                cpumask_set_cpu(i, &cpu_sibling_map[cpu]);
                                cpumask_set_cpu(cpu, &cpu_sibling_map[i]);
                        }
@@ -134,8 +133,7 @@ void calculate_cpu_foreign_map(void)
        for_each_online_cpu(i) {
                core_present = 0;
                for_each_cpu(k, &temp_foreign_map)
-                       if (cpu_data[i].package == cpu_data[k].package &&
-                           cpu_core(&cpu_data[i]) == cpu_core(&cpu_data[k]))
+                       if (cpus_are_siblings(i, k))
                                core_present = 1;
                if (!core_present)
                        cpumask_set_cpu(i, &temp_foreign_map);
@@ -186,11 +184,11 @@ void mips_smp_send_ipi_mask(const struct cpumask *mask, unsigned int action)
 
        if (mips_cpc_present()) {
                for_each_cpu(cpu, mask) {
-                       core = cpu_core(&cpu_data[cpu]);
-
-                       if (core == cpu_core(&current_cpu_data))
+                       if (cpus_are_siblings(cpu, smp_processor_id()))
                                continue;
 
+                       core = cpu_core(&cpu_data[cpu]);
+
                        while (!cpumask_test_cpu(cpu, &cpu_coherent_mask)) {
                                mips_cm_lock_other(core, 0);
                                mips_cpc_lock_other(core);
index 6041b6104f3dc6259bfe37389bf7093675a6d28d..72b5e47286b4b7bb3747fcbf91623259febba0ab 100644 (file)
@@ -37,7 +37,7 @@ static int cps_nc_enter(struct cpuidle_device *dev,
         * TODO: don't treat core 0 specially, just prevent the final core
         * TODO: remap interrupt affinity temporarily
         */
-       if (!cpu_core(&cpu_data[dev->cpu]) && (index > STATE_NC_WAIT))
+       if (cpus_are_siblings(0, dev->cpu) && (index > STATE_NC_WAIT))
                index = STATE_NC_WAIT;
 
        /* Select the appropriate cps_pm_state */
index 14461cbfab2fa234d365a947cc4e3d68e90378ed..66f97fde13d80053ef6d67cb1fef7677e0d6e8b8 100644 (file)
@@ -101,7 +101,7 @@ static void mips_mt_send_ipi(struct irq_data *d, unsigned int cpu)
        local_irq_save(flags);
 
        /* We can only send IPIs to VPEs within the local core */
-       WARN_ON(cpu_data[cpu].core != current_cpu_data.core);
+       WARN_ON(!cpus_are_siblings(smp_processor_id(), cpu));
 
        vpflags = dvpe();
        settc(cpu_vpe_id(&cpu_data[cpu]));