Skip to content

Commit 00efaa0

Browse files
wildea01Russell King
authored andcommitted
ARM: 7812/1: rwlocks: retry trylock operation if strex fails on free lock
Commit 15e7e5c ("ARM: 7749/1: spinlock: retry trylock operation if strex fails on free lock") modifying our arch_spin_trylock to retry the acquisition if the lock appeared uncontended, but the strex failed. This patch does the same for rwlocks, which were missed by the original patch. Signed-off-by: Will Deacon <[email protected]> Signed-off-by: Russell King <[email protected]>
1 parent afa31d8 commit 00efaa0

File tree

1 file changed

+30
-19
lines changed

1 file changed

+30
-19
lines changed

arch/arm/include/asm/spinlock.h

Lines changed: 30 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -168,17 +168,20 @@ static inline void arch_write_lock(arch_rwlock_t *rw)
168168

169169
static inline int arch_write_trylock(arch_rwlock_t *rw)
170170
{
171-
unsigned long tmp;
171+
unsigned long contended, res;
172172

173-
__asm__ __volatile__(
174-
" ldrex %0, [%1]\n"
175-
" teq %0, #0\n"
176-
" strexeq %0, %2, [%1]"
177-
: "=&r" (tmp)
178-
: "r" (&rw->lock), "r" (0x80000000)
179-
: "cc");
173+
do {
174+
__asm__ __volatile__(
175+
" ldrex %0, [%2]\n"
176+
" mov %1, #0\n"
177+
" teq %0, #0\n"
178+
" strexeq %1, %3, [%2]"
179+
: "=&r" (contended), "=&r" (res)
180+
: "r" (&rw->lock), "r" (0x80000000)
181+
: "cc");
182+
} while (res);
180183

181-
if (tmp == 0) {
184+
if (!contended) {
182185
smp_mb();
183186
return 1;
184187
} else {
@@ -254,18 +257,26 @@ static inline void arch_read_unlock(arch_rwlock_t *rw)
254257

255258
static inline int arch_read_trylock(arch_rwlock_t *rw)
256259
{
257-
unsigned long tmp, tmp2 = 1;
260+
unsigned long contended, res;
258261

259-
__asm__ __volatile__(
260-
" ldrex %0, [%2]\n"
261-
" adds %0, %0, #1\n"
262-
" strexpl %1, %0, [%2]\n"
263-
: "=&r" (tmp), "+r" (tmp2)
264-
: "r" (&rw->lock)
265-
: "cc");
262+
do {
263+
__asm__ __volatile__(
264+
" ldrex %0, [%2]\n"
265+
" mov %1, #0\n"
266+
" adds %0, %0, #1\n"
267+
" strexpl %1, %0, [%2]"
268+
: "=&r" (contended), "=&r" (res)
269+
: "r" (&rw->lock)
270+
: "cc");
271+
} while (res);
266272

267-
smp_mb();
268-
return tmp2 == 0;
273+
/* If the lock is negative, then it is already held for write. */
274+
if (contended < 0x80000000) {
275+
smp_mb();
276+
return 1;
277+
} else {
278+
return 0;
279+
}
269280
}
270281

271282
/* read_can_lock - would read_trylock() succeed? */

0 commit comments

Comments
 (0)