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 <ak@suse.de>
Cc: Marin Mitov <mitov@issp.bas.bg>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: <stable@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
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 @@
{
unsigned long bclock, now;
+ preempt_disable(); /* TSC's are per-cpu */
rdtscl(bclock);
do {
rep_nop();
rdtscl(now);
} while ((now-bclock) < loops);
+ preempt_enable();
}
/*