Messages in this thread Patch in this message | | | Date | Wed, 7 May 2008 11:49:49 -0700 (PDT) | From | Christoph Lameter <> | Subject | Spinlocks: Factor our GENERIC_LOCKBREAK in order to avoid spin with irqs disable |
| |
Subject: Spinlocks: Factor our GENERIC_LOCKBREAK in order to avoid spin with irqs disabled
The nice spinlock functions that enable interrupts while spinning are only usable if GENERIC_LOCKBREAK is set (and we do not debug locks but lock debugging would not be used for a production configuration).
Factor out the dependencies on the ->lock_break field from the nice functions into a set of BREAKLOCK macros (cannot be functions since the type of the lock variable varies).
The nice spinlock function can then also be used if !GENERIC_LOCKBREAK
Signed-off-by: Christoph Lameter <clameter@sgi.com>
--- kernel/spinlock.c | 40 ++++++++++++++++++++++++++++++---------- 1 file changed, 30 insertions(+), 10 deletions(-)
Index: linux-2.6/kernel/spinlock.c =================================================================== --- linux-2.6.orig/kernel/spinlock.c 2008-05-07 11:19:31.000000000 -0700 +++ linux-2.6/kernel/spinlock.c 2008-05-07 11:40:56.000000000 -0700 @@ -65,7 +65,7 @@ EXPORT_SYMBOL(_write_trylock); * even on CONFIG_PREEMPT, because lockdep assumes that interrupts are * not re-enabled during lock-acquire (which the preempt-spin-ops do): */ -#if !defined(CONFIG_GENERIC_LOCKBREAK) || defined(CONFIG_DEBUG_LOCK_ALLOC) +#ifdef CONFIG_DEBUG_LOCK_ALLOC void __lockfunc _read_lock(rwlock_t *lock) { @@ -192,7 +192,7 @@ void __lockfunc _write_lock(rwlock_t *lo EXPORT_SYMBOL(_write_lock); -#else /* CONFIG_PREEMPT: */ +#else /* CONFIG_DEBUG_LOCK_ALLOC: */ /* * This could be a long-held lock. We both prepare to spin for a long @@ -201,6 +201,28 @@ EXPORT_SYMBOL(_write_lock); * * (We do this in a function because inlining it would be excessive.) */ +#ifdef CONFIG_GENERIC_LOCKBREAK + +#define BREAKLOCK(lock) (lock)->break_lock + +#define BREAKLOCK_ENABLE(lock) \ +do { \ + if (!(lock)->break_lock) \ + (lock)->break_lock = 1; \ +} while (0) + +#define BREAKLOCK_DISABLE(lock) \ +do { \ + (lock)->break_lock = 0; \ +} while (0) + +#else + +#define BREAKLOCK(lock) 0 +#define BREAKLOCK_ENABLE(lock) do { } while (0) +#define BREAKLOCK_DISABLE(lock) do { } while (0) + +#endif #define BUILD_LOCK_OPS(op, locktype) \ void __lockfunc _##op##_lock(locktype##_t *lock) \ @@ -211,12 +233,11 @@ void __lockfunc _##op##_lock(locktype##_ break; \ preempt_enable(); \ \ - if (!(lock)->break_lock) \ - (lock)->break_lock = 1; \ - while (!op##_can_lock(lock) && (lock)->break_lock) \ + BREAKLOCK_ENABLE(lock); \ + while (!op##_can_lock(lock) && BREAKLOCK(lock)) \ _raw_##op##_relax(&lock->raw_lock); \ } \ - (lock)->break_lock = 0; \ + BREAKLOCK_DISABLE(lock); \ } \ \ EXPORT_SYMBOL(_##op##_lock); \ @@ -233,12 +254,11 @@ unsigned long __lockfunc _##op##_lock_ir local_irq_restore(flags); \ preempt_enable(); \ \ - if (!(lock)->break_lock) \ - (lock)->break_lock = 1; \ - while (!op##_can_lock(lock) && (lock)->break_lock) \ + BREAKLOCK_ENABLE(lock); \ + while (!op##_can_lock(lock) && BREAKLOCK(lock)) \ _raw_##op##_relax(&lock->raw_lock); \ } \ - (lock)->break_lock = 0; \ + BREAKLOCK_DISABLE(lock); \ return flags; \ } \ \
| |