MIPS: Support CPU topology files in sysfs
authorHuacai Chen <chenhc@lemote.com>
Thu, 26 Jun 2014 03:41:26 +0000 (11:41 +0800)
committerRalf Baechle <ralf@linux-mips.org>
Wed, 30 Jul 2014 19:45:39 +0000 (21:45 +0200)
This patch is prepared for Loongson's NUMA support, it offer meaningful
sysfs files such as physical_package_id, core_id, core_siblings and
thread_siblings in /sys/devices/system/cpu/cpu?/topology.

Signed-off-by: Huacai Chen <chenhc@lemote.com>
Reviewed-by: Andreas Herrmann <andreas.herrmann@caviumnetworks.com>
Cc: John Crispin <john@phrozen.org>
Cc: Steven J. Hill <Steven.Hill@imgtec.com>
Cc: Aurelien Jarno <aurelien@aurel32.net>
Cc: linux-mips@linux-mips.org
Cc: Fuxin Zhang <zhangfx@lemote.com>
Cc: Zhangjin Wu <wuzhangjin@gmail.com>
Patchwork: https://patchwork.linux-mips.org/patch/7184/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
arch/mips/include/asm/cpu-info.h
arch/mips/include/asm/smp.h
arch/mips/kernel/proc.c
arch/mips/kernel/smp.c

index a28e3de473d235bb902e351144bcda52c11e60f5..6690d7af0a03c7068fd73a60852a1542827aee55 100644 (file)
@@ -61,6 +61,7 @@ struct cpuinfo_mips {
        struct cache_desc       scache; /* Secondary cache */
        struct cache_desc       tcache; /* Tertiary/split secondary cache */
        int                     srsets; /* Shadow register sets */
+       int                     package;/* physical package number */
        int                     core;   /* physical core number */
 #ifdef CONFIG_64BIT
        int                     vmbits; /* Virtual memory size in bits */
index b037334fca22ed297475e54dd99c317764d15f65..1e0f20a9cddaa0caac16e0e5adfe09537cdce1dc 100644 (file)
@@ -22,6 +22,7 @@
 
 extern int smp_num_siblings;
 extern cpumask_t cpu_sibling_map[];
+extern cpumask_t cpu_core_map[];
 
 #define raw_smp_processor_id() (current_thread_info()->cpu)
 
@@ -36,6 +37,11 @@ extern int __cpu_logical_map[NR_CPUS];
 
 #define NO_PROC_ID     (-1)
 
+#define topology_physical_package_id(cpu)      (cpu_data[cpu].package)
+#define topology_core_id(cpu)                  (cpu_data[cpu].core)
+#define topology_core_cpumask(cpu)             (&cpu_core_map[cpu])
+#define topology_thread_cpumask(cpu)           (&cpu_sibling_map[cpu])
+
 #define SMP_RESCHEDULE_YOURSELF 0x1    /* XXX braindead */
 #define SMP_CALL_FUNCTION      0x2
 /* Octeon - Tell another core to flush its icache */
index 037a44d962f37e1b94251f13b054103e6cbb1ff5..62c4439a147beb3b9ff3027b9d32c895be43b345 100644 (file)
@@ -123,6 +123,7 @@ static int show_cpuinfo(struct seq_file *m, void *v)
                      cpu_data[n].srsets);
        seq_printf(m, "kscratch registers\t: %d\n",
                      hweight8(cpu_data[n].kscratch_mask));
+       seq_printf(m, "package\t\t\t: %d\n", cpu_data[n].package);
        seq_printf(m, "core\t\t\t: %d\n", cpu_data[n].core);
 
        sprintf(fmt, "VCE%%c exceptions\t\t: %s\n",
index 9bad52ede9031f0ed0ab1f9d3390be0aef2073d3..c94c4e92e17d4bb964a5ca8e7ae77523c4fa44a4 100644 (file)
@@ -59,9 +59,16 @@ EXPORT_SYMBOL(smp_num_siblings);
 cpumask_t cpu_sibling_map[NR_CPUS] __read_mostly;
 EXPORT_SYMBOL(cpu_sibling_map);
 
+/* representing the core map of multi-core chips of each logical CPU */
+cpumask_t cpu_core_map[NR_CPUS] __read_mostly;
+EXPORT_SYMBOL(cpu_core_map);
+
 /* representing cpus for which sibling maps can be computed */
 static cpumask_t cpu_sibling_setup_map;
 
+/* representing cpus for which core maps can be computed */
+static cpumask_t cpu_core_setup_map;
+
 cpumask_t cpu_coherent_mask;
 
 static inline void set_cpu_sibling_map(int cpu)
@@ -72,7 +79,8 @@ static inline void set_cpu_sibling_map(int cpu)
 
        if (smp_num_siblings > 1) {
                for_each_cpu_mask(i, cpu_sibling_setup_map) {
-                       if (cpu_data[cpu].core == cpu_data[i].core) {
+                       if (cpu_data[cpu].package == cpu_data[i].package &&
+                                   cpu_data[cpu].core == cpu_data[i].core) {
                                cpu_set(i, cpu_sibling_map[cpu]);
                                cpu_set(cpu, cpu_sibling_map[i]);
                        }
@@ -81,6 +89,20 @@ static inline void set_cpu_sibling_map(int cpu)
                cpu_set(cpu, cpu_sibling_map[cpu]);
 }
 
+static inline void set_cpu_core_map(int cpu)
+{
+       int i;
+
+       cpu_set(cpu, cpu_core_setup_map);
+
+       for_each_cpu_mask(i, cpu_core_setup_map) {
+               if (cpu_data[cpu].package == cpu_data[i].package) {
+                       cpu_set(i, cpu_core_map[cpu]);
+                       cpu_set(cpu, cpu_core_map[i]);
+               }
+       }
+}
+
 struct plat_smp_ops *mp_ops;
 EXPORT_SYMBOL(mp_ops);
 
@@ -122,6 +144,7 @@ asmlinkage void start_secondary(void)
        set_cpu_online(cpu, true);
 
        set_cpu_sibling_map(cpu);
+       set_cpu_core_map(cpu);
 
        cpu_set(cpu, cpu_callin_map);
 
@@ -175,6 +198,7 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
        current_thread_info()->cpu = 0;
        mp_ops->prepare_cpus(max_cpus);
        set_cpu_sibling_map(0);
+       set_cpu_core_map(0);
 #ifndef CONFIG_HOTPLUG_CPU
        init_cpu_present(cpu_possible_mask);
 #endif