aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2007-06-20 19:22:34 -0400
committerRalf Baechle <ralf@linux-mips.org>2007-07-06 11:17:11 -0400
commit4b3e975e4a06f1710693c5aa51b8f98facfa9863 (patch)
tree2ccc660fda43c6e0906b3d03bfb39a9dd81f7ade
parentfde97822a295da9dffa4af643b49a58ffc4516ad (diff)
[MIPS] Fix scheduling latency issue on 24K, 34K and 74K cores
The idle loop goes to sleep using the WAIT instruction if !need_resched(). This has is suffering from from a race condition that if if just after need_resched has returned 0 an interrupt might set TIF_NEED_RESCHED but we've just completed the test so go to sleep anyway. This would be trivial to fix by just disabling interrupts during that sequence as in: local_irq_disable(); if (!need_resched()) __asm__("wait"); local_irq_enable(); but the processor architecture leaves it undefined if a processor calling WAIT with interrupts disabled will ever restart its pipeline and indeed some processors have made use of the freedom provided by the architecture definition. This has been resolved and the Config7.WII bit indicates that the use of WAIT is safe on 24K, 24KE and 34K cores. It also is safe on 74K starting revision 2.1.0 so enable the use of WAIT with interrupts disabled for 74K based on a c0_prid of at least that. Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
-rw-r--r--arch/mips/kernel/cpu-probe.c15
-rw-r--r--include/asm-mips/mipsregs.h2
2 files changed, 15 insertions, 2 deletions
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c
index 0fc90ba16ae1..b12eeee0e974 100644
--- a/arch/mips/kernel/cpu-probe.c
+++ b/arch/mips/kernel/cpu-probe.c
@@ -137,13 +137,24 @@ static inline void check_wait(void)
137 case CPU_4KEC: 137 case CPU_4KEC:
138 case CPU_4KSC: 138 case CPU_4KSC:
139 case CPU_5KC: 139 case CPU_5KC:
140 case CPU_24K:
141 case CPU_25KF: 140 case CPU_25KF:
141 case CPU_PR4450:
142 cpu_wait = r4k_wait;
143 break;
144
145 case CPU_24K:
142 case CPU_34K: 146 case CPU_34K:
147 cpu_wait = r4k_wait;
148 if (read_c0_config7() & MIPS_CONF7_WII)
149 cpu_wait = r4k_wait_irqoff;
150 break;
151
143 case CPU_74K: 152 case CPU_74K:
144 case CPU_PR4450:
145 cpu_wait = r4k_wait; 153 cpu_wait = r4k_wait;
154 if ((c->processor_id & 0xff) >= PRID_REV_ENCODE_332(2, 1, 0))
155 cpu_wait = r4k_wait_irqoff;
146 break; 156 break;
157
147 case CPU_TX49XX: 158 case CPU_TX49XX:
148 cpu_wait = r4k_wait_irqoff; 159 cpu_wait = r4k_wait_irqoff;
149 break; 160 break;
diff --git a/include/asm-mips/mipsregs.h b/include/asm-mips/mipsregs.h
index 9985cb7c16e7..89c81922d47c 100644
--- a/include/asm-mips/mipsregs.h
+++ b/include/asm-mips/mipsregs.h
@@ -534,6 +534,8 @@
534#define MIPS_CONF3_LPA (_ULCAST_(1) << 7) 534#define MIPS_CONF3_LPA (_ULCAST_(1) << 7)
535#define MIPS_CONF3_DSP (_ULCAST_(1) << 10) 535#define MIPS_CONF3_DSP (_ULCAST_(1) << 10)
536 536
537#define MIPS_CONF7_WII (_ULCAST_(1) << 31)
538
537/* 539/*
538 * Bits in the MIPS32/64 coprocessor 1 (FPU) revision register. 540 * Bits in the MIPS32/64 coprocessor 1 (FPU) revision register.
539 */ 541 */