ARM: 7812/1: rwlocks: retry trylock operation if strex fails on free lock
Commit 15e7e5c1eb
("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 <will.deacon@arm.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
This commit is contained in:
committed by
Russell King
parent
afa31d8eb8
commit
00efaa0250
@@ -168,17 +168,20 @@ static inline void arch_write_lock(arch_rwlock_t *rw)
|
|||||||
|
|
||||||
static inline int arch_write_trylock(arch_rwlock_t *rw)
|
static inline int arch_write_trylock(arch_rwlock_t *rw)
|
||||||
{
|
{
|
||||||
unsigned long tmp;
|
unsigned long contended, res;
|
||||||
|
|
||||||
__asm__ __volatile__(
|
do {
|
||||||
" ldrex %0, [%1]\n"
|
__asm__ __volatile__(
|
||||||
" teq %0, #0\n"
|
" ldrex %0, [%2]\n"
|
||||||
" strexeq %0, %2, [%1]"
|
" mov %1, #0\n"
|
||||||
: "=&r" (tmp)
|
" teq %0, #0\n"
|
||||||
: "r" (&rw->lock), "r" (0x80000000)
|
" strexeq %1, %3, [%2]"
|
||||||
: "cc");
|
: "=&r" (contended), "=&r" (res)
|
||||||
|
: "r" (&rw->lock), "r" (0x80000000)
|
||||||
|
: "cc");
|
||||||
|
} while (res);
|
||||||
|
|
||||||
if (tmp == 0) {
|
if (!contended) {
|
||||||
smp_mb();
|
smp_mb();
|
||||||
return 1;
|
return 1;
|
||||||
} else {
|
} else {
|
||||||
@@ -254,18 +257,26 @@ static inline void arch_read_unlock(arch_rwlock_t *rw)
|
|||||||
|
|
||||||
static inline int arch_read_trylock(arch_rwlock_t *rw)
|
static inline int arch_read_trylock(arch_rwlock_t *rw)
|
||||||
{
|
{
|
||||||
unsigned long tmp, tmp2 = 1;
|
unsigned long contended, res;
|
||||||
|
|
||||||
__asm__ __volatile__(
|
do {
|
||||||
" ldrex %0, [%2]\n"
|
__asm__ __volatile__(
|
||||||
" adds %0, %0, #1\n"
|
" ldrex %0, [%2]\n"
|
||||||
" strexpl %1, %0, [%2]\n"
|
" mov %1, #0\n"
|
||||||
: "=&r" (tmp), "+r" (tmp2)
|
" adds %0, %0, #1\n"
|
||||||
: "r" (&rw->lock)
|
" strexpl %1, %0, [%2]"
|
||||||
: "cc");
|
: "=&r" (contended), "=&r" (res)
|
||||||
|
: "r" (&rw->lock)
|
||||||
|
: "cc");
|
||||||
|
} while (res);
|
||||||
|
|
||||||
smp_mb();
|
/* If the lock is negative, then it is already held for write. */
|
||||||
return tmp2 == 0;
|
if (contended < 0x80000000) {
|
||||||
|
smp_mb();
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* read_can_lock - would read_trylock() succeed? */
|
/* read_can_lock - would read_trylock() succeed? */
|
||||||
|
Reference in New Issue
Block a user