aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/include/asm/rwsem.h28
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 */
127static inline int __down_write_trylock(struct rw_semaphore *sem) 127static 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/*