aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86_64/kernel
diff options
context:
space:
mode:
authorAndi Kleen <ak@suse.de>2006-12-06 20:14:03 -0500
committerAndi Kleen <andi@basil.nowhere.org>2006-12-06 20:14:03 -0500
commit72690a21188586022a9e65cb6f1cc8845167555a (patch)
tree6ddd4a04307867128100dbd1906eec5a89f88662 /arch/x86_64/kernel
parent63cb683c6ed56a420ba60df6a5b206a44e3f85fe (diff)
[PATCH] x86: Don't use nested idle loops
Currently the idle loop has two nested loops -- one high level in cpu_idle and in some low level idle functions another one. Looping in the low level idle functions breaks the idle notifiers because interrupts waking up sleep states need to execute exit_idle() which is only in cpu_idle(). So don't do that, only loop in cpu_idle(). This only removes code. In some cases e.g. poll_idle the idle loop is a little longer now because cpu_idle checks more things. I hope that isn't a problem ACPI idle doesn't change behaviour because it never looped anyways. Cc: len.brown@intel.com Cc: eranian@hpl.hp.com Signed-off-by: Andi Kleen <ak@suse.de>
Diffstat (limited to 'arch/x86_64/kernel')
-rw-r--r--arch/x86_64/kernel/process.c30
1 files changed, 9 insertions, 21 deletions
diff --git a/arch/x86_64/kernel/process.c b/arch/x86_64/kernel/process.c
index 7451a4c43c16..0b7b4caa4f74 100644
--- a/arch/x86_64/kernel/process.c
+++ b/arch/x86_64/kernel/process.c
@@ -108,17 +108,15 @@ void exit_idle(void)
108 */ 108 */
109static void default_idle(void) 109static void default_idle(void)
110{ 110{
111 local_irq_enable();
112
113 current_thread_info()->status &= ~TS_POLLING; 111 current_thread_info()->status &= ~TS_POLLING;
114 smp_mb__after_clear_bit(); 112 smp_mb__after_clear_bit();
115 while (!need_resched()) { 113 local_irq_disable();
116 local_irq_disable(); 114 if (!need_resched()) {
117 if (!need_resched()) 115 /* Enables interrupts one instruction before HLT.
118 safe_halt(); 116 x86 special cases this so there is no race. */
119 else 117 safe_halt();
120 local_irq_enable(); 118 } else
121 } 119 local_irq_enable();
122 current_thread_info()->status |= TS_POLLING; 120 current_thread_info()->status |= TS_POLLING;
123} 121}
124 122
@@ -129,16 +127,7 @@ static void default_idle(void)
129 */ 127 */
130static void poll_idle (void) 128static void poll_idle (void)
131{ 129{
132 local_irq_enable(); 130 cpu_relax();
133
134 asm volatile(
135 "2:"
136 "testl %0,%1;"
137 "rep; nop;"
138 "je 2b;"
139 : :
140 "i" (_TIF_NEED_RESCHED),
141 "m" (current_thread_info()->flags));
142} 131}
143 132
144void cpu_idle_wait(void) 133void cpu_idle_wait(void)
@@ -257,8 +246,7 @@ void mwait_idle_with_hints(unsigned long eax, unsigned long ecx)
257static void mwait_idle(void) 246static void mwait_idle(void)
258{ 247{
259 local_irq_enable(); 248 local_irq_enable();
260 while (!need_resched()) 249 mwait_idle_with_hints(0,0);
261 mwait_idle_with_hints(0,0);
262} 250}
263 251
264void __cpuinit select_idle_routine(const struct cpuinfo_x86 *c) 252void __cpuinit select_idle_routine(const struct cpuinfo_x86 *c)