diff options
author | Andi Kleen <ak@suse.de> | 2006-12-07 02:14:00 +0100 |
---|---|---|
committer | Andi Kleen <andi@basil.nowhere.org> | 2006-12-07 02:14:00 +0100 |
commit | 87e1652c7863b9ae406ff37f33c7ec2bb494d7b1 (patch) | |
tree | a87d98504d20aaf6e7dba583f11c730be02ce3d5 | |
parent | a63954b5cad5765e52870bb649992bf636f32a6b (diff) | |
download | linux-stable-87e1652c7863b9ae406ff37f33c7ec2bb494d7b1.tar.gz linux-stable-87e1652c7863b9ae406ff37f33c7ec2bb494d7b1.tar.bz2 linux-stable-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>
-rw-r--r-- | include/asm-x86_64/spinlock.h | 29 |
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) { |