Commit 8522703f authored by Ingo Molnar's avatar Ingo Molnar Committed by Linus Torvalds

[PATCH] nonintrusive spin-polling loop in kernel/spinlock.c

This re-implements the nonintrusive spin-polling loop for the
SMP+PREEMPT spinlock/rwlock variants, using the new *_can_lock()
primitives.  (The patch also adds *_can_lock() to the UP branch of
spinlock.h, for completeness.)

build- and boot-tested on x86 SMP+PREEMPT and SMP+!PREEMPT.
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 8edee057
...@@ -221,6 +221,8 @@ typedef struct { ...@@ -221,6 +221,8 @@ typedef struct {
#define _raw_read_unlock(lock) do { (void)(lock); } while(0) #define _raw_read_unlock(lock) do { (void)(lock); } while(0)
#define _raw_write_lock(lock) do { (void)(lock); } while(0) #define _raw_write_lock(lock) do { (void)(lock); } while(0)
#define _raw_write_unlock(lock) do { (void)(lock); } while(0) #define _raw_write_unlock(lock) do { (void)(lock); } while(0)
#define read_can_lock(lock) (((void)(lock), 1))
#define write_can_lock(lock) (((void)(lock), 1))
#define _raw_read_trylock(lock) ({ (void)(lock); (1); }) #define _raw_read_trylock(lock) ({ (void)(lock); (1); })
#define _raw_write_trylock(lock) ({ (void)(lock); (1); }) #define _raw_write_trylock(lock) ({ (void)(lock); (1); })
......
...@@ -174,7 +174,7 @@ EXPORT_SYMBOL(_write_lock); ...@@ -174,7 +174,7 @@ EXPORT_SYMBOL(_write_lock);
*/ */
#define BUILD_LOCK_OPS(op, locktype) \ #define BUILD_LOCK_OPS(op, locktype) \
void __lockfunc _##op##_lock(locktype *lock) \ void __lockfunc _##op##_lock(locktype##_t *lock) \
{ \ { \
preempt_disable(); \ preempt_disable(); \
for (;;) { \ for (;;) { \
...@@ -183,6 +183,7 @@ void __lockfunc _##op##_lock(locktype *lock) \ ...@@ -183,6 +183,7 @@ void __lockfunc _##op##_lock(locktype *lock) \
preempt_enable(); \ preempt_enable(); \
if (!(lock)->break_lock) \ if (!(lock)->break_lock) \
(lock)->break_lock = 1; \ (lock)->break_lock = 1; \
while (!op##_can_lock(lock) && (lock)->break_lock) \
cpu_relax(); \ cpu_relax(); \
preempt_disable(); \ preempt_disable(); \
} \ } \
...@@ -190,7 +191,7 @@ void __lockfunc _##op##_lock(locktype *lock) \ ...@@ -190,7 +191,7 @@ void __lockfunc _##op##_lock(locktype *lock) \
\ \
EXPORT_SYMBOL(_##op##_lock); \ EXPORT_SYMBOL(_##op##_lock); \
\ \
unsigned long __lockfunc _##op##_lock_irqsave(locktype *lock) \ unsigned long __lockfunc _##op##_lock_irqsave(locktype##_t *lock) \
{ \ { \
unsigned long flags; \ unsigned long flags; \
\ \
...@@ -204,6 +205,7 @@ unsigned long __lockfunc _##op##_lock_irqsave(locktype *lock) \ ...@@ -204,6 +205,7 @@ unsigned long __lockfunc _##op##_lock_irqsave(locktype *lock) \
preempt_enable(); \ preempt_enable(); \
if (!(lock)->break_lock) \ if (!(lock)->break_lock) \
(lock)->break_lock = 1; \ (lock)->break_lock = 1; \
while (!op##_can_lock(lock) && (lock)->break_lock) \
cpu_relax(); \ cpu_relax(); \
preempt_disable(); \ preempt_disable(); \
} \ } \
...@@ -212,14 +214,14 @@ unsigned long __lockfunc _##op##_lock_irqsave(locktype *lock) \ ...@@ -212,14 +214,14 @@ unsigned long __lockfunc _##op##_lock_irqsave(locktype *lock) \
\ \
EXPORT_SYMBOL(_##op##_lock_irqsave); \ EXPORT_SYMBOL(_##op##_lock_irqsave); \
\ \
void __lockfunc _##op##_lock_irq(locktype *lock) \ void __lockfunc _##op##_lock_irq(locktype##_t *lock) \
{ \ { \
_##op##_lock_irqsave(lock); \ _##op##_lock_irqsave(lock); \
} \ } \
\ \
EXPORT_SYMBOL(_##op##_lock_irq); \ EXPORT_SYMBOL(_##op##_lock_irq); \
\ \
void __lockfunc _##op##_lock_bh(locktype *lock) \ void __lockfunc _##op##_lock_bh(locktype##_t *lock) \
{ \ { \
unsigned long flags; \ unsigned long flags; \
\ \
...@@ -244,9 +246,9 @@ EXPORT_SYMBOL(_##op##_lock_bh) ...@@ -244,9 +246,9 @@ EXPORT_SYMBOL(_##op##_lock_bh)
* _[spin|read|write]_lock_irqsave() * _[spin|read|write]_lock_irqsave()
* _[spin|read|write]_lock_bh() * _[spin|read|write]_lock_bh()
*/ */
BUILD_LOCK_OPS(spin, spinlock_t); BUILD_LOCK_OPS(spin, spinlock);
BUILD_LOCK_OPS(read, rwlock_t); BUILD_LOCK_OPS(read, rwlock);
BUILD_LOCK_OPS(write, rwlock_t); BUILD_LOCK_OPS(write, rwlock);
#endif /* CONFIG_PREEMPT */ #endif /* CONFIG_PREEMPT */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment