aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/i386/kernel/process.c30
-rw-r--r--arch/x86_64/kernel/process.c30
2 files changed, 18 insertions, 42 deletions
diff --git a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c
index 8749b10d3805..8f42659ef9d2 100644
--- a/arch/i386/kernel/process.c
+++ b/arch/i386/kernel/process.c
@@ -100,22 +100,18 @@ EXPORT_SYMBOL(enable_hlt);
100 */ 100 */
101void default_idle(void) 101void default_idle(void)
102{ 102{
103 local_irq_enable();
104
105 if (!hlt_counter && boot_cpu_data.hlt_works_ok) { 103 if (!hlt_counter && boot_cpu_data.hlt_works_ok) {
106 current_thread_info()->status &= ~TS_POLLING; 104 current_thread_info()->status &= ~TS_POLLING;
107 smp_mb__after_clear_bit(); 105 smp_mb__after_clear_bit();
108 while (!need_resched()) { 106 local_irq_disable();
109 local_irq_disable(); 107 if (!need_resched())
110 if (!need_resched()) 108 safe_halt(); /* enables interrupts racelessly */
111 safe_halt(); 109 else
112 else 110 local_irq_enable();
113 local_irq_enable();
114 }
115 current_thread_info()->status |= TS_POLLING; 111 current_thread_info()->status |= TS_POLLING;
116 } else { 112 } else {
117 while (!need_resched()) 113 /* loop is done by the caller */
118 cpu_relax(); 114 cpu_relax();
119 } 115 }
120} 116}
121#ifdef CONFIG_APM_MODULE 117#ifdef CONFIG_APM_MODULE
@@ -129,14 +125,7 @@ EXPORT_SYMBOL(default_idle);
129 */ 125 */
130static void poll_idle (void) 126static void poll_idle (void)
131{ 127{
132 local_irq_enable(); 128 cpu_relax();
133
134 asm volatile(
135 "2:"
136 "testl %0, %1;"
137 "rep; nop;"
138 "je 2b;"
139 : : "i"(_TIF_NEED_RESCHED), "m" (current_thread_info()->flags));
140} 129}
141 130
142#ifdef CONFIG_HOTPLUG_CPU 131#ifdef CONFIG_HOTPLUG_CPU
@@ -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 __devinit select_idle_routine(const struct cpuinfo_x86 *c) 252void __devinit select_idle_routine(const struct cpuinfo_x86 *c)
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)