Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=35d5d08a085c56f153458c3f5d8ce24123617faf
Commit:     35d5d08a085c56f153458c3f5d8ce24123617faf
Parent:     7eea436433b7b18045f272562e256976f593f7c0
Author:     Andrew Morton <[EMAIL PROTECTED]>
AuthorDate: Wed Nov 14 17:00:41 2007 -0800
Committer:  Linus Torvalds <[EMAIL PROTECTED]>
CommitDate: Wed Nov 14 18:45:44 2007 -0800

    x86: disable preemption in delay_tsc()
    
    Marin Mitov points out that delay_tsc() can misbehave if it is preempted and
    rescheduled on a different CPU which has a skewed TSC.  Fix it by disabling
    preemption.
    
    (I assume that the worst-case behaviour here is a stall of 2^32 cycles)
    
    Cc: Andi Kleen <[EMAIL PROTECTED]>
    Cc: Marin Mitov <[EMAIL PROTECTED]>
    Cc: Thomas Gleixner <[EMAIL PROTECTED]>
    Cc: Ingo Molnar <[EMAIL PROTECTED]>
    Cc: <[EMAIL PROTECTED]>
    Signed-off-by: Andrew Morton <[EMAIL PROTECTED]>
    Signed-off-by: Linus Torvalds <[EMAIL PROTECTED]>
---
 arch/x86/lib/delay_32.c |    3 +++
 arch/x86/lib/delay_64.c |   11 +++++++----
 2 files changed, 10 insertions(+), 4 deletions(-)

diff --git a/arch/x86/lib/delay_32.c b/arch/x86/lib/delay_32.c
index 952e7a8..aad9d95 100644
--- a/arch/x86/lib/delay_32.c
+++ b/arch/x86/lib/delay_32.c
@@ -12,6 +12,7 @@
 
 #include <linux/module.h>
 #include <linux/sched.h>
+#include <linux/preempt.h>
 #include <linux/delay.h>
 
 #include <asm/processor.h>
@@ -42,11 +43,13 @@ static void delay_tsc(unsigned long loops)
 {
        unsigned long bclock, now;
 
+       preempt_disable();              /* TSC's are per-cpu */
        rdtscl(bclock);
        do {
                rep_nop();
                rdtscl(now);
        } while ((now-bclock) < loops);
+       preempt_enable();
 }
 
 /*
diff --git a/arch/x86/lib/delay_64.c b/arch/x86/lib/delay_64.c
index 0ebbfb9..45cdd3f 100644
--- a/arch/x86/lib/delay_64.c
+++ b/arch/x86/lib/delay_64.c
@@ -10,7 +10,9 @@
 
 #include <linux/module.h>
 #include <linux/sched.h>
+#include <linux/preempt.h>
 #include <linux/delay.h>
+
 #include <asm/delay.h>
 #include <asm/msr.h>
 
@@ -27,14 +29,15 @@ int read_current_timer(unsigned long *timer_value)
 void __delay(unsigned long loops)
 {
        unsigned bclock, now;
-       
+
+       preempt_disable();              /* TSC's are pre-cpu */
        rdtscl(bclock);
-       do
-       {
+       do {
                rep_nop(); 
                rdtscl(now);
        }
-       while((now-bclock) < loops);
+       while ((now-bclock) < loops);
+       preempt_enable();
 }
 EXPORT_SYMBOL(__delay);
 
-
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