summaryrefslogtreecommitdiff
path: root/include/asm-x86_64/spinlock.h
diff options
context:
space:
mode:
authorAndi Kleen <ak@suse.de>2006-12-07 02:14:00 +0100
committerAndi Kleen <andi@basil.nowhere.org>2006-12-07 02:14:00 +0100
commit87e1652c7863b9ae406ff37f33c7ec2bb494d7b1 (patch)
treea87d98504d20aaf6e7dba583f11c730be02ce3d5 /include/asm-x86_64/spinlock.h
parenta63954b5cad5765e52870bb649992bf636f32a6b (diff)
downloadlwn-87e1652c7863b9ae406ff37f33c7ec2bb494d7b1.tar.gz
lwn-87e1652c7863b9ae406ff37f33c7ec2bb494d7b1.zip
[PATCH] x86-64: Don't keep interrupts disabled while spinning in spinlocks
Follows i386. Based on patch from some folks at Google (MikeW, Edward G.?), but completely redone by AK. Signed-off-by: Andi Kleen <ak@suse.de>
Diffstat (limited to 'include/asm-x86_64/spinlock.h')
-rw-r--r--include/asm-x86_64/spinlock.h29
1 files changed, 28 insertions, 1 deletions
diff --git a/include/asm-x86_64/spinlock.h b/include/asm-x86_64/spinlock.h
index 05ef097ba55b..88bf981e73cf 100644
--- a/include/asm-x86_64/spinlock.h
+++ b/include/asm-x86_64/spinlock.h
@@ -36,7 +36,34 @@ static inline void __raw_spin_lock(raw_spinlock_t *lock)
"2:\t" : "=m" (lock->slock) : : "memory");
}
-#define __raw_spin_lock_flags(lock, flags) __raw_spin_lock(lock)
+/*
+ * Same as __raw_spin_lock, but reenable interrupts during spinning.
+ */
+#ifndef CONFIG_PROVE_LOCKING
+static inline void __raw_spin_lock_flags(raw_spinlock_t *lock, unsigned long flags)
+{
+ asm volatile(
+ "\n1:\t"
+ LOCK_PREFIX " ; decl %0\n\t"
+ "jns 5f\n"
+ "testl $0x200, %1\n\t" /* interrupts were disabled? */
+ "jz 4f\n\t"
+ "sti\n"
+ "3:\t"
+ "rep;nop\n\t"
+ "cmpl $0, %0\n\t"
+ "jle 3b\n\t"
+ "cli\n\t"
+ "jmp 1b\n"
+ "4:\t"
+ "rep;nop\n\t"
+ "cmpl $0, %0\n\t"
+ "jg 1b\n\t"
+ "jmp 4b\n"
+ "5:\n\t"
+ : "+m" (lock->slock) : "r" ((unsigned)flags) : "memory");
+}
+#endif
static inline int __raw_spin_trylock(raw_spinlock_t *lock)
{