diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2007-03-02 15:42:04 -0500 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2008-01-29 05:14:57 -0500 |
commit | 0ab7aefc4d43a6dee26c891b41ef9c7a67d2379b (patch) | |
tree | 4a627b7079979ad43b08cef297b2a6eb78d0a78e /arch | |
parent | 92b1e6a64a8d9d5ed3ec8797eed8b36e2164a410 (diff) |
[MIPS] MT: Scheduler support for SMT
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/mips/Kconfig | 14 | ||||
-rw-r--r-- | arch/mips/kernel/proc.c | 1 | ||||
-rw-r--r-- | arch/mips/kernel/smp-mt.c | 6 | ||||
-rw-r--r-- | arch/mips/kernel/smp.c | 30 |
4 files changed, 50 insertions, 1 deletions
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 11bc17ce0ebf..d5a89f3fdfd3 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig | |||
@@ -1442,6 +1442,7 @@ config MIPS_MT_SMP | |||
1442 | select MIPS_MT | 1442 | select MIPS_MT |
1443 | select NR_CPUS_DEFAULT_2 | 1443 | select NR_CPUS_DEFAULT_2 |
1444 | select SMP | 1444 | select SMP |
1445 | select SYS_SUPPORTS_SCHED_SMT if SMP | ||
1445 | select SYS_SUPPORTS_SMP | 1446 | select SYS_SUPPORTS_SMP |
1446 | help | 1447 | help |
1447 | This is a kernel model which is also known a VSMP or lately | 1448 | This is a kernel model which is also known a VSMP or lately |
@@ -1468,6 +1469,19 @@ endchoice | |||
1468 | config MIPS_MT | 1469 | config MIPS_MT |
1469 | bool | 1470 | bool |
1470 | 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 | |||
1484 | |||
1471 | config SYS_SUPPORTS_MULTITHREADING | 1485 | config SYS_SUPPORTS_MULTITHREADING |
1472 | bool | 1486 | bool |
1473 | 1487 | ||
diff --git a/arch/mips/kernel/proc.c b/arch/mips/kernel/proc.c index 6e6e947cce1e..34dd22838fdb 100644 --- a/arch/mips/kernel/proc.c +++ b/arch/mips/kernel/proc.c | |||
@@ -62,6 +62,7 @@ static int show_cpuinfo(struct seq_file *m, void *v) | |||
62 | ); | 62 | ); |
63 | seq_printf(m, "shadow register sets\t: %d\n", | 63 | seq_printf(m, "shadow register sets\t: %d\n", |
64 | cpu_data[n].srsets); | 64 | cpu_data[n].srsets); |
65 | seq_printf(m, "core\t\t\t: %d\n", cpu_data[n].core); | ||
65 | 66 | ||
66 | sprintf(fmt, "VCE%%c exceptions\t\t: %s\n", | 67 | sprintf(fmt, "VCE%%c exceptions\t\t: %s\n", |
67 | cpu_has_vce ? "%u" : "not available"); | 68 | cpu_has_vce ? "%u" : "not available"); |
diff --git a/arch/mips/kernel/smp-mt.c b/arch/mips/kernel/smp-mt.c index 94e210cc6cb6..2ab0b7eeaa7e 100644 --- a/arch/mips/kernel/smp-mt.c +++ b/arch/mips/kernel/smp-mt.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/cpumask.h> | 22 | #include <linux/cpumask.h> |
23 | #include <linux/interrupt.h> | 23 | #include <linux/interrupt.h> |
24 | #include <linux/compiler.h> | 24 | #include <linux/compiler.h> |
25 | #include <linux/smp.h> | ||
25 | 26 | ||
26 | #include <asm/atomic.h> | 27 | #include <asm/atomic.h> |
27 | #include <asm/cacheflush.h> | 28 | #include <asm/cacheflush.h> |
@@ -30,7 +31,6 @@ | |||
30 | #include <asm/system.h> | 31 | #include <asm/system.h> |
31 | #include <asm/hardirq.h> | 32 | #include <asm/hardirq.h> |
32 | #include <asm/mmu_context.h> | 33 | #include <asm/mmu_context.h> |
33 | #include <asm/smp.h> | ||
34 | #include <asm/time.h> | 34 | #include <asm/time.h> |
35 | #include <asm/mipsregs.h> | 35 | #include <asm/mipsregs.h> |
36 | #include <asm/mipsmtregs.h> | 36 | #include <asm/mipsmtregs.h> |
@@ -223,6 +223,7 @@ static void __init smp_tc_init(unsigned int tc, unsigned int mvpconf0) | |||
223 | void __init plat_smp_setup(void) | 223 | void __init plat_smp_setup(void) |
224 | { | 224 | { |
225 | unsigned int mvpconf0, ntc, tc, ncpu = 0; | 225 | unsigned int mvpconf0, ntc, tc, ncpu = 0; |
226 | unsigned int nvpe; | ||
226 | 227 | ||
227 | #ifdef CONFIG_MIPS_MT_FPAFF | 228 | #ifdef CONFIG_MIPS_MT_FPAFF |
228 | /* If we have an FPU, enroll ourselves in the FPU-full mask */ | 229 | /* If we have an FPU, enroll ourselves in the FPU-full mask */ |
@@ -242,6 +243,9 @@ void __init plat_smp_setup(void) | |||
242 | mvpconf0 = read_c0_mvpconf0(); | 243 | mvpconf0 = read_c0_mvpconf0(); |
243 | ntc = (mvpconf0 & MVPCONF0_PTC) >> MVPCONF0_PTC_SHIFT; | 244 | ntc = (mvpconf0 & MVPCONF0_PTC) >> MVPCONF0_PTC_SHIFT; |
244 | 245 | ||
246 | nvpe = ((mvpconf0 & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT) + 1; | ||
247 | smp_num_siblings = nvpe; | ||
248 | |||
245 | /* we'll always have more TC's than VPE's, so loop setting everything | 249 | /* we'll always have more TC's than VPE's, so loop setting everything |
246 | to a sensible state */ | 250 | to a sensible state */ |
247 | for (tc = 0; tc <= ntc; tc++) { | 251 | for (tc = 0; tc <= ntc; tc++) { |
diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c index 63989e9df4f9..335be9bcf0dc 100644 --- a/arch/mips/kernel/smp.c +++ b/arch/mips/kernel/smp.c | |||
@@ -56,6 +56,34 @@ EXPORT_SYMBOL(cpu_online_map); | |||
56 | extern void __init calibrate_delay(void); | 56 | extern void __init calibrate_delay(void); |
57 | extern void cpu_idle(void); | 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 | * First C code run on the secondary CPUs after being started up by | 88 | * First C code run on the secondary CPUs after being started up by |
61 | * the master. | 89 | * the master. |
@@ -85,6 +113,7 @@ asmlinkage __cpuinit void start_secondary(void) | |||
85 | cpu_data[cpu].udelay_val = loops_per_jiffy; | 113 | cpu_data[cpu].udelay_val = loops_per_jiffy; |
86 | 114 | ||
87 | prom_smp_finish(); | 115 | prom_smp_finish(); |
116 | set_cpu_sibling_map(cpu); | ||
88 | 117 | ||
89 | cpu_set(cpu, cpu_callin_map); | 118 | cpu_set(cpu, cpu_callin_map); |
90 | 119 | ||
@@ -258,6 +287,7 @@ void __init smp_prepare_cpus(unsigned int max_cpus) | |||
258 | init_new_context(current, &init_mm); | 287 | init_new_context(current, &init_mm); |
259 | current_thread_info()->cpu = 0; | 288 | current_thread_info()->cpu = 0; |
260 | plat_prepare_cpus(max_cpus); | 289 | plat_prepare_cpus(max_cpus); |
290 | set_cpu_sibling_map(0); | ||
261 | #ifndef CONFIG_HOTPLUG_CPU | 291 | #ifndef CONFIG_HOTPLUG_CPU |
262 | cpu_present_map = cpu_possible_map; | 292 | cpu_present_map = cpu_possible_map; |
263 | #endif | 293 | #endif |