Commit 0ab7aefc4d43a6dee26c891b41ef9c7a67d2379b
1 parent
92b1e6a64a
Exists in
master
and in
7 other branches
[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
arch/mips/Kconfig
... | ... | @@ -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
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 */ |