Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=62be90012c507b2bf1047eb2eaa1e9151f7172fe
Commit:     62be90012c507b2bf1047eb2eaa1e9151f7172fe
Parent:     06bfb7eb1535822a3338ffea9918e22215abed90
Author:     Satyam Sharma <[EMAIL PROTECTED]>
AuthorDate: Thu Aug 16 06:09:25 2007 +0530
Committer:  Linus Torvalds <[EMAIL PROTECTED]>
CommitDate: Sat Aug 18 09:54:44 2007 -0700

    i386: Fix a couple busy loops in mach_wakecpu.h:wait_for_init_deassert()
    
    Use cpu_relax() in the busy loops, as atomic_read() doesn't automatically
    imply volatility for i386 and x86_64. x86_64 doesn't have this issue because
    it open-codes the while loop in smpboot.c:smp_callin() itself that already
    uses cpu_relax().
    
    For i386, however, smpboot.c:smp_callin() calls wait_for_init_deassert()
    which is buggy for mach-default and mach-es7000 cases.
    
    [ I test-built a kernel -- smp_callin() itself got inlined in its only
      callsite, smpboot.c:start_secondary() -- and the relevant piece of
      code disassembles to the following:
    
    0xc1019704 <start_secondary+12>:        mov    0xc144c4c8,%eax
    0xc1019709 <start_secondary+17>:        test   %eax,%eax
    0xc101970b <start_secondary+19>:        je     0xc1019709 
<start_secondary+17>
    
      init_deasserted (at 0xc144c4c8) gets fetched into %eax only once and
      then we loop over the test of the stale value in the register only,
      so these look like real bugs to me. With the fix below, this becomes:
    
    0xc1019706 <start_secondary+14>:        pause
    0xc1019708 <start_secondary+16>:        cmpl   $0x0,0xc144c4c8
    0xc101970f <start_secondary+23>:        je     0xc1019706 
<start_secondary+14>
    
      which looks nice and healthy. ]
    
    Thanks to Heiko Carstens for noticing this.
    
    Signed-off-by: Satyam Sharma <[EMAIL PROTECTED]>
    Cc: Heiko Carstens <[EMAIL PROTECTED]>
    Signed-off-by: Linus Torvalds <[EMAIL PROTECTED]>
---
 include/asm-i386/mach-default/mach_wakecpu.h |    3 ++-
 include/asm-i386/mach-es7000/mach_wakecpu.h  |    3 ++-
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/include/asm-i386/mach-default/mach_wakecpu.h 
b/include/asm-i386/mach-default/mach_wakecpu.h
index 673b85c..3ebb178 100644
--- a/include/asm-i386/mach-default/mach_wakecpu.h
+++ b/include/asm-i386/mach-default/mach_wakecpu.h
@@ -15,7 +15,8 @@
 
 static inline void wait_for_init_deassert(atomic_t *deassert)
 {
-       while (!atomic_read(deassert));
+       while (!atomic_read(deassert))
+               cpu_relax();
        return;
 }
 
diff --git a/include/asm-i386/mach-es7000/mach_wakecpu.h 
b/include/asm-i386/mach-es7000/mach_wakecpu.h
index efc903b..84ff583 100644
--- a/include/asm-i386/mach-es7000/mach_wakecpu.h
+++ b/include/asm-i386/mach-es7000/mach_wakecpu.h
@@ -31,7 +31,8 @@ wakeup_secondary_cpu(int phys_apicid, unsigned long start_eip)
 static inline void wait_for_init_deassert(atomic_t *deassert)
 {
 #ifdef WAKE_SECONDARY_VIA_INIT
-       while (!atomic_read(deassert));
+       while (!atomic_read(deassert))
+               cpu_relax();
 #endif
        return;
 }
-
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