diff options
Diffstat (limited to 'arch/x86')
-rw-r--r-- | arch/x86/include/asm/rwsem.h | 28 |
1 files changed, 21 insertions, 7 deletions
diff --git a/arch/x86/include/asm/rwsem.h b/arch/x86/include/asm/rwsem.h index 2dbe4a721ce5..cad82c9c2fde 100644 --- a/arch/x86/include/asm/rwsem.h +++ b/arch/x86/include/asm/rwsem.h | |||
@@ -105,8 +105,8 @@ static inline void __down_write_nested(struct rw_semaphore *sem, int subclass) | |||
105 | asm volatile("# beginning down_write\n\t" | 105 | asm volatile("# beginning down_write\n\t" |
106 | LOCK_PREFIX " xadd %1,(%2)\n\t" | 106 | LOCK_PREFIX " xadd %1,(%2)\n\t" |
107 | /* adds 0xffff0001, returns the old value */ | 107 | /* adds 0xffff0001, returns the old value */ |
108 | " test %1,%1\n\t" | 108 | " test " __ASM_SEL(%w1,%k1) "," __ASM_SEL(%w1,%k1) "\n\t" |
109 | /* was the count 0 before? */ | 109 | /* was the active mask 0 before? */ |
110 | " jz 1f\n" | 110 | " jz 1f\n" |
111 | " call call_rwsem_down_write_failed\n" | 111 | " call call_rwsem_down_write_failed\n" |
112 | "1:\n" | 112 | "1:\n" |
@@ -126,11 +126,25 @@ static inline void __down_write(struct rw_semaphore *sem) | |||
126 | */ | 126 | */ |
127 | static inline int __down_write_trylock(struct rw_semaphore *sem) | 127 | static inline int __down_write_trylock(struct rw_semaphore *sem) |
128 | { | 128 | { |
129 | long ret = cmpxchg(&sem->count, RWSEM_UNLOCKED_VALUE, | 129 | long result, tmp; |
130 | RWSEM_ACTIVE_WRITE_BIAS); | 130 | asm volatile("# beginning __down_write_trylock\n\t" |
131 | if (ret == RWSEM_UNLOCKED_VALUE) | 131 | " mov %0,%1\n\t" |
132 | return 1; | 132 | "1:\n\t" |
133 | return 0; | 133 | " test " __ASM_SEL(%w1,%k1) "," __ASM_SEL(%w1,%k1) "\n\t" |
134 | /* was the active mask 0 before? */ | ||
135 | " jnz 2f\n\t" | ||
136 | " mov %1,%2\n\t" | ||
137 | " add %3,%2\n\t" | ||
138 | LOCK_PREFIX " cmpxchg %2,%0\n\t" | ||
139 | " jnz 1b\n\t" | ||
140 | "2:\n\t" | ||
141 | " sete %b1\n\t" | ||
142 | " movzbl %b1, %k1\n\t" | ||
143 | "# ending __down_write_trylock\n\t" | ||
144 | : "+m" (sem->count), "=&a" (result), "=&r" (tmp) | ||
145 | : "er" (RWSEM_ACTIVE_WRITE_BIAS) | ||
146 | : "memory", "cc"); | ||
147 | return result; | ||
134 | } | 148 | } |
135 | 149 | ||
136 | /* | 150 | /* |