Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=71416bea5afa9e5a6c76c1509ab69c46c857a2bb
Commit:     71416bea5afa9e5a6c76c1509ab69c46c857a2bb
Parent:     39d3520c92cf7a28c07229ca00cc35a1e8026c77
Author:     Dimitri Sivanich <[EMAIL PROTECTED]>
AuthorDate: Tue Aug 7 08:49:32 2007 -0500
Committer:  Tony Luck <[EMAIL PROTECTED]>
CommitDate: Mon Aug 13 10:17:23 2007 -0700

    [IA64] disable irq's and check need_resched before safe_halt
    
    While sending interrupts to a cpu to repeatedly wake a thread, on occasion
    that thread will take a full timer tick cycle (4002 usec in my case)
    to wakeup.
    
    The problem concerns a race condition in the code around the safe_halt()
    call in the default_idle() routine.  Setting 'nohalt' on the kernel
    command line causes the long wakeups to disappear.
    
    void
    default_idle (void)
    {
            local_irq_enable();
            while (!need_resched()) {
    -->             if (can_do_pal_halt)
    -->                     safe_halt();
                    else
    
    A timer tick could arrive between the check for !need_resched and the
    actual call to safe_halt() (which does a pal call to PAL_HALT_LIGHT).
    By the time the timer tick completes, a thread that might now need to run
    could get held up for as long as a timer tick waiting for the halted cpu.
    
    I'm proposing that we disable irq's and check need_resched again before
    calling safe_halt().  Does anyone see any problem with this approach?
    
    Signed-off-by: Dimitri Sivanich <[EMAIL PROTECTED]>
    Signed-off-by: Tony Luck <[EMAIL PROTECTED]>
---
 arch/ia64/kernel/process.c |   10 +++++++---
 1 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c
index 4158906..c613fc0 100644
--- a/arch/ia64/kernel/process.c
+++ b/arch/ia64/kernel/process.c
@@ -198,9 +198,13 @@ default_idle (void)
 {
        local_irq_enable();
        while (!need_resched()) {
-               if (can_do_pal_halt)
-                       safe_halt();
-               else
+               if (can_do_pal_halt) {
+                       local_irq_disable();
+                       if (!need_resched()) {
+                               safe_halt();
+                       }
+                       local_irq_enable();
+               } else
                        cpu_relax();
        }
 }
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to