Commit 0ab7aefc4d43a6dee26c891b41ef9c7a67d2379b

Authored by Ralf Baechle
1 parent 92b1e6a64a

[MIPS] MT: Scheduler support for SMT

Signed-off-by: Ralf Baechle <ralf@linux-mips.org>

Showing 7 changed files with 73 additions and 2 deletions Side-by-side Diff

... ... @@ -1442,6 +1442,7 @@
1442 1442 select MIPS_MT
1443 1443 select NR_CPUS_DEFAULT_2
1444 1444 select SMP
  1445 + select SYS_SUPPORTS_SCHED_SMT if SMP
1445 1446 select SYS_SUPPORTS_SMP
1446 1447 help
1447 1448 This is a kernel model which is also known a VSMP or lately
... ... @@ -1467,6 +1468,19 @@
1467 1468  
1468 1469 config MIPS_MT
1469 1470 bool
  1471 +
  1472 +config SCHED_SMT
  1473 + bool "SMT (multithreading) scheduler support"
  1474 + depends on SYS_SUPPORTS_SCHED_SMT
  1475 + default n
  1476 + help
  1477 + SMT scheduler support improves the CPU scheduler's decision making
  1478 + when dealing with MIPS MT enabled cores at a cost of slightly
  1479 + increased overhead in some places. If unsure say N here.
  1480 +
  1481 +config SYS_SUPPORTS_SCHED_SMT
  1482 + bool
  1483 +
1470 1484  
1471 1485 config SYS_SUPPORTS_MULTITHREADING
1472 1486 bool
arch/mips/kernel/proc.c
... ... @@ -62,6 +62,7 @@
62 62 );
63 63 seq_printf(m, "shadow register sets\t: %d\n",
64 64 cpu_data[n].srsets);
  65 + seq_printf(m, "core\t\t\t: %d\n", cpu_data[n].core);
65 66  
66 67 sprintf(fmt, "VCE%%c exceptions\t\t: %s\n",
67 68 cpu_has_vce ? "%u" : "not available");
arch/mips/kernel/smp-mt.c
... ... @@ -22,6 +22,7 @@
22 22 #include <linux/cpumask.h>
23 23 #include <linux/interrupt.h>
24 24 #include <linux/compiler.h>
  25 +#include <linux/smp.h>
25 26  
26 27 #include <asm/atomic.h>
27 28 #include <asm/cacheflush.h>
... ... @@ -30,7 +31,6 @@
30 31 #include <asm/system.h>
31 32 #include <asm/hardirq.h>
32 33 #include <asm/mmu_context.h>
33   -#include <asm/smp.h>
34 34 #include <asm/time.h>
35 35 #include <asm/mipsregs.h>
36 36 #include <asm/mipsmtregs.h>
... ... @@ -223,6 +223,7 @@
223 223 void __init plat_smp_setup(void)
224 224 {
225 225 unsigned int mvpconf0, ntc, tc, ncpu = 0;
  226 + unsigned int nvpe;
226 227  
227 228 #ifdef CONFIG_MIPS_MT_FPAFF
228 229 /* If we have an FPU, enroll ourselves in the FPU-full mask */
... ... @@ -241,6 +242,9 @@
241 242  
242 243 mvpconf0 = read_c0_mvpconf0();
243 244 ntc = (mvpconf0 & MVPCONF0_PTC) >> MVPCONF0_PTC_SHIFT;
  245 +
  246 + nvpe = ((mvpconf0 & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT) + 1;
  247 + smp_num_siblings = nvpe;
244 248  
245 249 /* we'll always have more TC's than VPE's, so loop setting everything
246 250 to a sensible state */
arch/mips/kernel/smp.c
... ... @@ -56,6 +56,34 @@
56 56 extern void __init calibrate_delay(void);
57 57 extern void cpu_idle(void);
58 58  
  59 +/* Number of TCs (or siblings in Intel speak) per CPU core */
  60 +int smp_num_siblings = 1;
  61 +EXPORT_SYMBOL(smp_num_siblings);
  62 +
  63 +/* representing the TCs (or siblings in Intel speak) of each logical CPU */
  64 +cpumask_t cpu_sibling_map[NR_CPUS] __read_mostly;
  65 +EXPORT_SYMBOL(cpu_sibling_map);
  66 +
  67 +/* representing cpus for which sibling maps can be computed */
  68 +static cpumask_t cpu_sibling_setup_map;
  69 +
  70 +static inline void set_cpu_sibling_map(int cpu)
  71 +{
  72 + int i;
  73 +
  74 + cpu_set(cpu, cpu_sibling_setup_map);
  75 +
  76 + if (smp_num_siblings > 1) {
  77 + for_each_cpu_mask(i, cpu_sibling_setup_map) {
  78 + if (cpu_data[cpu].core == cpu_data[i].core) {
  79 + cpu_set(i, cpu_sibling_map[cpu]);
  80 + cpu_set(cpu, cpu_sibling_map[i]);
  81 + }
  82 + }
  83 + } else
  84 + cpu_set(cpu, cpu_sibling_map[cpu]);
  85 +}
  86 +
59 87 /*
60 88 * First C code run on the secondary CPUs after being started up by
61 89 * the master.
... ... @@ -85,6 +113,7 @@
85 113 cpu_data[cpu].udelay_val = loops_per_jiffy;
86 114  
87 115 prom_smp_finish();
  116 + set_cpu_sibling_map(cpu);
88 117  
89 118 cpu_set(cpu, cpu_callin_map);
90 119  
... ... @@ -258,6 +287,7 @@
258 287 init_new_context(current, &init_mm);
259 288 current_thread_info()->cpu = 0;
260 289 plat_prepare_cpus(max_cpus);
  290 + set_cpu_sibling_map(0);
261 291 #ifndef CONFIG_HOTPLUG_CPU
262 292 cpu_present_map = cpu_possible_map;
263 293 #endif
include/asm-mips/cpu-info.h
... ... @@ -55,6 +55,7 @@
55 55 struct cache_desc scache; /* Secondary cache */
56 56 struct cache_desc tcache; /* Tertiary/split secondary cache */
57 57 int srsets; /* Shadow register sets */
  58 + int core; /* physical core number */
58 59 #if defined(CONFIG_MIPS_MT_SMTC)
59 60 /*
60 61 * In the MIPS MT "SMTC" model, each TC is considered
61 62  
... ... @@ -63,8 +64,10 @@
63 64 * to all TCs within the same VPE.
64 65 */
65 66 int vpe_id; /* Virtual Processor number */
66   - int tc_id; /* Thread Context number */
67 67 #endif /* CONFIG_MIPS_MT */
  68 +#ifdef CONFIG_MIPS_MT_SMTC
  69 + int tc_id; /* Thread Context number */
  70 +#endif
68 71 void *data; /* Additional data */
69 72 } __attribute__((aligned(SMP_CACHE_BYTES)));
70 73  
include/asm-mips/smp.h
... ... @@ -20,6 +20,9 @@
20 20 #include <linux/cpumask.h>
21 21 #include <asm/atomic.h>
22 22  
  23 +extern int smp_num_siblings;
  24 +extern cpumask_t cpu_sibling_map[];
  25 +
23 26 #define raw_smp_processor_id() (current_thread_info()->cpu)
24 27  
25 28 /* Map from cpu id to sequential logical cpu number. This will only
include/asm-mips/topology.h
  1 +/*
  2 + * This file is subject to the terms and conditions of the GNU General Public
  3 + * License. See the file "COPYING" in the main directory of this archive
  4 + * for more details.
  5 + *
  6 + * Copyright (C) 2007 by Ralf Baechle
  7 + */
  8 +#ifndef __ASM_TOPOLOGY_H
  9 +#define __ASM_TOPOLOGY_H
  10 +
1 11 #include <topology.h>
  12 +
  13 +#ifdef CONFIG_SMP
  14 +#define smt_capable() (smp_num_siblings > 1)
  15 +#endif
  16 +
  17 +#endif /* __ASM_TOPOLOGY_H */