diff options
-rw-r--r-- | include/asm-x86_64/rwlock.h | 14 | ||||
-rw-r--r-- | include/asm-x86_64/spinlock.h | 71 |
2 files changed, 41 insertions, 44 deletions
diff --git a/include/asm-x86_64/rwlock.h b/include/asm-x86_64/rwlock.h index 28a080d23119..72aeebed920b 100644 --- a/include/asm-x86_64/rwlock.h +++ b/include/asm-x86_64/rwlock.h | |||
@@ -21,18 +21,6 @@ | |||
21 | #define RW_LOCK_BIAS 0x01000000 | 21 | #define RW_LOCK_BIAS 0x01000000 |
22 | #define RW_LOCK_BIAS_STR "0x01000000" | 22 | #define RW_LOCK_BIAS_STR "0x01000000" |
23 | 23 | ||
24 | #define __build_read_lock(rw) \ | 24 | /* Actual code is in asm/spinlock.h or in arch/x86_64/lib/rwlock.S */ |
25 | asm volatile(LOCK_PREFIX "subl $1,(%0)\n\t" \ | ||
26 | "jns 1f\n" \ | ||
27 | "call __read_lock_failed\n" \ | ||
28 | "1:\n" \ | ||
29 | ::"D" (rw), "i" (RW_LOCK_BIAS) : "memory") | ||
30 | |||
31 | #define __build_write_lock(rw) \ | ||
32 | asm volatile(LOCK_PREFIX "subl %1,(%0)\n\t" \ | ||
33 | "jz 1f\n" \ | ||
34 | "\tcall __write_lock_failed\n\t" \ | ||
35 | "1:\n" \ | ||
36 | ::"D" (rw), "i" (RW_LOCK_BIAS) : "memory") | ||
37 | 25 | ||
38 | #endif | 26 | #endif |
diff --git a/include/asm-x86_64/spinlock.h b/include/asm-x86_64/spinlock.h index 1d0733b38a4b..be7a9e629fb2 100644 --- a/include/asm-x86_64/spinlock.h +++ b/include/asm-x86_64/spinlock.h | |||
@@ -16,30 +16,23 @@ | |||
16 | * (the type definitions are in asm/spinlock_types.h) | 16 | * (the type definitions are in asm/spinlock_types.h) |
17 | */ | 17 | */ |
18 | 18 | ||
19 | #define __raw_spin_is_locked(x) \ | 19 | static inline int __raw_spin_is_locked(raw_spinlock_t *lock) |
20 | (*(volatile signed int *)(&(x)->slock) <= 0) | 20 | { |
21 | 21 | return *(volatile signed int *)(&(lock)->slock) <= 0; | |
22 | #define __raw_spin_lock_string \ | 22 | } |
23 | "\n1:\t" \ | ||
24 | LOCK_PREFIX " ; decl %0\n\t" \ | ||
25 | "jns 2f\n" \ | ||
26 | "3:\n" \ | ||
27 | "rep;nop\n\t" \ | ||
28 | "cmpl $0,%0\n\t" \ | ||
29 | "jle 3b\n\t" \ | ||
30 | "jmp 1b\n" \ | ||
31 | "2:\t" \ | ||
32 | |||
33 | #define __raw_spin_lock_string_up \ | ||
34 | "\n\tdecl %0" | ||
35 | |||
36 | #define __raw_spin_unlock_string \ | ||
37 | "movl $1,%0" \ | ||
38 | :"=m" (lock->slock) : : "memory" | ||
39 | 23 | ||
40 | static inline void __raw_spin_lock(raw_spinlock_t *lock) | 24 | static inline void __raw_spin_lock(raw_spinlock_t *lock) |
41 | { | 25 | { |
42 | asm volatile(__raw_spin_lock_string : "=m" (lock->slock) : : "memory"); | 26 | asm volatile( |
27 | "\n1:\t" | ||
28 | LOCK_PREFIX " ; decl %0\n\t" | ||
29 | "jns 2f\n" | ||
30 | "3:\n" | ||
31 | "rep;nop\n\t" | ||
32 | "cmpl $0,%0\n\t" | ||
33 | "jle 3b\n\t" | ||
34 | "jmp 1b\n" | ||
35 | "2:\t" : "=m" (lock->slock) : : "memory"); | ||
43 | } | 36 | } |
44 | 37 | ||
45 | #define __raw_spin_lock_flags(lock, flags) __raw_spin_lock(lock) | 38 | #define __raw_spin_lock_flags(lock, flags) __raw_spin_lock(lock) |
@@ -48,7 +41,7 @@ static inline int __raw_spin_trylock(raw_spinlock_t *lock) | |||
48 | { | 41 | { |
49 | int oldval; | 42 | int oldval; |
50 | 43 | ||
51 | __asm__ __volatile__( | 44 | asm volatile( |
52 | "xchgl %0,%1" | 45 | "xchgl %0,%1" |
53 | :"=q" (oldval), "=m" (lock->slock) | 46 | :"=q" (oldval), "=m" (lock->slock) |
54 | :"0" (0) : "memory"); | 47 | :"0" (0) : "memory"); |
@@ -58,13 +51,14 @@ static inline int __raw_spin_trylock(raw_spinlock_t *lock) | |||
58 | 51 | ||
59 | static inline void __raw_spin_unlock(raw_spinlock_t *lock) | 52 | static inline void __raw_spin_unlock(raw_spinlock_t *lock) |
60 | { | 53 | { |
61 | __asm__ __volatile__( | 54 | asm volatile("movl $1,%0" :"=m" (lock->slock) :: "memory"); |
62 | __raw_spin_unlock_string | ||
63 | ); | ||
64 | } | 55 | } |
65 | 56 | ||
66 | #define __raw_spin_unlock_wait(lock) \ | 57 | static inline void __raw_spin_unlock_wait(raw_spinlock_t *lock) |
67 | do { while (__raw_spin_is_locked(lock)) cpu_relax(); } while (0) | 58 | { |
59 | while (__raw_spin_is_locked(lock)) | ||
60 | cpu_relax(); | ||
61 | } | ||
68 | 62 | ||
69 | /* | 63 | /* |
70 | * Read-write spinlocks, allowing multiple readers | 64 | * Read-write spinlocks, allowing multiple readers |
@@ -80,17 +74,32 @@ static inline void __raw_spin_unlock(raw_spinlock_t *lock) | |||
80 | * with the high bit (sign) being the "contended" bit. | 74 | * with the high bit (sign) being the "contended" bit. |
81 | */ | 75 | */ |
82 | 76 | ||
83 | #define __raw_read_can_lock(x) ((int)(x)->lock > 0) | 77 | static inline int __raw_read_can_lock(raw_rwlock_t *lock) |
84 | #define __raw_write_can_lock(x) ((x)->lock == RW_LOCK_BIAS) | 78 | { |
79 | return (int)(lock)->lock > 0; | ||
80 | } | ||
81 | |||
82 | static inline int __raw_write_can_lock(raw_rwlock_t *lock) | ||
83 | { | ||
84 | return (lock)->lock == RW_LOCK_BIAS; | ||
85 | } | ||
85 | 86 | ||
86 | static inline void __raw_read_lock(raw_rwlock_t *rw) | 87 | static inline void __raw_read_lock(raw_rwlock_t *rw) |
87 | { | 88 | { |
88 | __build_read_lock(rw); | 89 | asm volatile(LOCK_PREFIX "subl $1,(%0)\n\t" |
90 | "jns 1f\n" | ||
91 | "call __read_lock_failed\n" | ||
92 | "1:\n" | ||
93 | ::"D" (rw), "i" (RW_LOCK_BIAS) : "memory"); | ||
89 | } | 94 | } |
90 | 95 | ||
91 | static inline void __raw_write_lock(raw_rwlock_t *rw) | 96 | static inline void __raw_write_lock(raw_rwlock_t *rw) |
92 | { | 97 | { |
93 | __build_write_lock(rw); | 98 | asm volatile(LOCK_PREFIX "subl %1,(%0)\n\t" |
99 | "jz 1f\n" | ||
100 | "\tcall __write_lock_failed\n\t" | ||
101 | "1:\n" | ||
102 | ::"D" (rw), "i" (RW_LOCK_BIAS) : "memory"); | ||
94 | } | 103 | } |
95 | 104 | ||
96 | static inline int __raw_read_trylock(raw_rwlock_t *lock) | 105 | static inline int __raw_read_trylock(raw_rwlock_t *lock) |