mirror of https://gitee.com/openkylin/linux.git
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:
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)
|
||||
{
|
||||
unsigned long tmp;
|
||||
unsigned long contended, res;
|
||||
|
||||
do {
|
||||
__asm__ __volatile__(
|
||||
" ldrex %0, [%1]\n"
|
||||
" teq %0, #0\n"
|
||||
" strexeq %0, %2, [%1]"
|
||||
: "=&r" (tmp)
|
||||
" ldrex %0, [%2]\n"
|
||||
" mov %1, #0\n"
|
||||
" teq %0, #0\n"
|
||||
" strexeq %1, %3, [%2]"
|
||||
: "=&r" (contended), "=&r" (res)
|
||||
: "r" (&rw->lock), "r" (0x80000000)
|
||||
: "cc");
|
||||
} while (res);
|
||||
|
||||
if (tmp == 0) {
|
||||
if (!contended) {
|
||||
smp_mb();
|
||||
return 1;
|
||||
} 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)
|
||||
{
|
||||
unsigned long tmp, tmp2 = 1;
|
||||
unsigned long contended, res;
|
||||
|
||||
do {
|
||||
__asm__ __volatile__(
|
||||
" ldrex %0, [%2]\n"
|
||||
" adds %0, %0, #1\n"
|
||||
" strexpl %1, %0, [%2]\n"
|
||||
: "=&r" (tmp), "+r" (tmp2)
|
||||
" ldrex %0, [%2]\n"
|
||||
" mov %1, #0\n"
|
||||
" adds %0, %0, #1\n"
|
||||
" strexpl %1, %0, [%2]"
|
||||
: "=&r" (contended), "=&r" (res)
|
||||
: "r" (&rw->lock)
|
||||
: "cc");
|
||||
} while (res);
|
||||
|
||||
/* If the lock is negative, then it is already held for write. */
|
||||
if (contended < 0x80000000) {
|
||||
smp_mb();
|
||||
return tmp2 == 0;
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* read_can_lock - would read_trylock() succeed? */
|
||||
|
|
Loading…
Reference in New Issue