aboutsummaryrefslogtreecommitdiffstats
path: root/arch/i386/kernel/process.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/i386/kernel/process.c')
-rw-r--r--arch/i386/kernel/process.c28
1 files changed, 16 insertions, 12 deletions
diff --git a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c
index b0a07801d9df..1e1fa3e391a3 100644
--- a/arch/i386/kernel/process.c
+++ b/arch/i386/kernel/process.c
@@ -236,20 +236,28 @@ EXPORT_SYMBOL_GPL(cpu_idle_wait);
236 * We execute MONITOR against need_resched and enter optimized wait state 236 * We execute MONITOR against need_resched and enter optimized wait state
237 * through MWAIT. Whenever someone changes need_resched, we would be woken 237 * through MWAIT. Whenever someone changes need_resched, we would be woken
238 * up from MWAIT (without an IPI). 238 * up from MWAIT (without an IPI).
239 *
240 * New with Core Duo processors, MWAIT can take some hints based on CPU
241 * capability.
239 */ 242 */
240static void mwait_idle(void) 243void mwait_idle_with_hints(unsigned long eax, unsigned long ecx)
241{ 244{
242 local_irq_enable(); 245 if (!need_resched()) {
243
244 while (!need_resched()) {
245 __monitor((void *)&current_thread_info()->flags, 0, 0); 246 __monitor((void *)&current_thread_info()->flags, 0, 0);
246 smp_mb(); 247 smp_mb();
247 if (need_resched()) 248 if (!need_resched())
248 break; 249 __mwait(eax, ecx);
249 __mwait(0, 0);
250 } 250 }
251} 251}
252 252
253/* Default MONITOR/MWAIT with no hints, used for default C1 state */
254static void mwait_idle(void)
255{
256 local_irq_enable();
257 while (!need_resched())
258 mwait_idle_with_hints(0, 0);
259}
260
253void __devinit select_idle_routine(const struct cpuinfo_x86 *c) 261void __devinit select_idle_routine(const struct cpuinfo_x86 *c)
254{ 262{
255 if (cpu_has(c, X86_FEATURE_MWAIT)) { 263 if (cpu_has(c, X86_FEATURE_MWAIT)) {
@@ -328,7 +336,6 @@ extern void kernel_thread_helper(void);
328int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) 336int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
329{ 337{
330 struct pt_regs regs; 338 struct pt_regs regs;
331 int err;
332 339
333 memset(&regs, 0, sizeof(regs)); 340 memset(&regs, 0, sizeof(regs));
334 341
@@ -343,10 +350,7 @@ int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
343 regs.eflags = X86_EFLAGS_IF | X86_EFLAGS_SF | X86_EFLAGS_PF | 0x2; 350 regs.eflags = X86_EFLAGS_IF | X86_EFLAGS_SF | X86_EFLAGS_PF | 0x2;
344 351
345 /* Ok, create the new process.. */ 352 /* Ok, create the new process.. */
346 err = do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, &regs, 0, NULL, NULL); 353 return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, &regs, 0, NULL, NULL);
347 if (err == 0) /* terminate kernel stack */
348 task_pt_regs(current)->eip = 0;
349 return err;
350} 354}
351EXPORT_SYMBOL(kernel_thread); 355EXPORT_SYMBOL(kernel_thread);
352 356