]> git.neil.brown.name Git - history.git/commitdiff
[PATCH] cpu_idle() startup race fix
authorAndrew Morton <akpm@osdl.org>
Fri, 1 Aug 2003 03:11:57 +0000 (20:11 -0700)
committerLinus Torvalds <torvalds@home.osdl.org>
Fri, 1 Aug 2003 03:11:57 +0000 (20:11 -0700)
Diagnosis from Christian Vogel <vogel@skunk.physik.uni-erlangen.de>

cpu_idle() tests pm_idle() just once then falls into the

while (!need_resched())
idle();

loop.

Problem is, that loop never terminates (need_resched() always returns false
on preemptive kernels).

The other problem is that ACPI updates pm_idle _after_ cpu_idle() has taken a
local copy.  So we always call default_idle(), even when pm_idle is pointing
at a new idle handler.

So fix it to pick up changed values of pm_idle() each time around the inner
loop.

arch/i386/kernel/process.c

index 61bc3326e287be6545ec682537df8cd6e3c4d98b..6908786e39a96c811497dc4dc9556f5db9e38dec 100644 (file)
@@ -138,12 +138,15 @@ void cpu_idle (void)
 {
        /* endless idle loop with no priority at all */
        while (1) {
-               void (*idle)(void) = pm_idle;
-               if (!idle)
-                       idle = default_idle;
-               irq_stat[smp_processor_id()].idle_timestamp = jiffies;
-               while (!need_resched())
+               while (!need_resched()) {
+                       void (*idle)(void) = pm_idle;
+
+                       if (!idle)
+                               idle = default_idle;
+
+                       irq_stat[smp_processor_id()].idle_timestamp = jiffies;
                        idle();
+               }
                schedule();
        }
 }