diff options
| author | Andrew Morton <akpm@osdl.org> | 2004-06-23 18:48:56 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2004-06-23 18:48:56 -0700 |
| commit | 36f9f2094996483001457fb02398d4b7eae170bd (patch) | |
| tree | 0e39898a3e14a0e5425c4b8ae692da7b1209e653 /include | |
| parent | 5e1c40de84c8e0514e8fe7e5db5087355dc00d5c (diff) | |
[PATCH] Allow i386 to reenable interrupts on lock contention
From: Zwane Mwaikambo <zwane@linuxpower.ca>
Following up on Keith's code, I adapted the i386 code to allow enabling
interrupts during contested locks depending on previous interrupt
enable status. Obviously there will be a text increase (only for non
CONFIG_SPINLINE case), although it doesn't seem so bad, there will be an
increased exit latency when we attempt a lock acquisition after spinning
due to the extra instructions. How much this will affect performance I'm
not sure yet as I haven't had time to micro bench.
text data bss dec hex filename
2628024 921731 0 3549755 362a3b vmlinux-after
2621369 921731 0 3543100 36103c vmlinux-before
2618313 919222 0 3537535 35fa7f vmlinux-spinline
The code has been stress tested on a 16x NUMAQ (courtesy OSDL).
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'include')
| -rw-r--r-- | include/asm-i386/spinlock.h | 32 |
1 files changed, 31 insertions, 1 deletions
diff --git a/include/asm-i386/spinlock.h b/include/asm-i386/spinlock.h index 8bd4f23a562e..d6dbfd469565 100644 --- a/include/asm-i386/spinlock.h +++ b/include/asm-i386/spinlock.h @@ -42,7 +42,6 @@ typedef struct { #define spin_is_locked(x) (*(volatile signed char *)(&(x)->lock) <= 0) #define spin_unlock_wait(x) do { barrier(); } while(spin_is_locked(x)) -#define _raw_spin_lock_flags(lock, flags) _raw_spin_lock(lock) #define spin_lock_string \ "\n1:\t" \ @@ -56,6 +55,23 @@ typedef struct { "jmp 1b\n" \ LOCK_SECTION_END +#define spin_lock_string_flags \ + "\n1:\t" \ + "lock ; decb %0\n\t" \ + "js 2f\n\t" \ + LOCK_SECTION_START("") \ + "2:\t" \ + "testl $0x200, %1\n\t" \ + "jz 3f\n\t" \ + "sti\n\t" \ + "3:\t" \ + "rep;nop\n\t" \ + "cmpb $0, %0\n\t" \ + "jle 3b\n\t" \ + "cli\n\t" \ + "jmp 1b\n" \ + LOCK_SECTION_END + /* * This works. Despite all the confusion. * (except on PPro SMP or if we are using OOSTORE) @@ -126,6 +142,20 @@ here: :"=m" (lock->lock) : : "memory"); } +static inline void _raw_spin_lock_flags (spinlock_t *lock, unsigned long flags) +{ +#ifdef CONFIG_DEBUG_SPINLOCK + __label__ here; +here: + if (unlikely(lock->magic != SPINLOCK_MAGIC)) { + printk("eip: %p\n", &&here); + BUG(); + } +#endif + __asm__ __volatile__( + spin_lock_string_flags + :"=m" (lock->lock) : "r" (flags) : "memory"); +} /* * Read-write spinlocks, allowing multiple readers |
