mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-28 14:44:10 +08:00
locking/mutex: Use try_cmpxchg()
For simpler and better code. Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Reviewed-by: Waiman Long <longman@redhat.com> Reviewed-by: Yanfei Xu <yanfei.xu@windriver.com> Link: https://lore.kernel.org/r/20210630154114.834438545@infradead.org
This commit is contained in:
parent
0e8a89d49d
commit
ab4e4d9f79
@ -100,7 +100,7 @@ static inline struct task_struct *__mutex_trylock_or_owner(struct mutex *lock)
|
||||
|
||||
owner = atomic_long_read(&lock->owner);
|
||||
for (;;) { /* must loop, can race against a flag */
|
||||
unsigned long old, flags = __owner_flags(owner);
|
||||
unsigned long flags = __owner_flags(owner);
|
||||
unsigned long task = owner & ~MUTEX_FLAGS;
|
||||
|
||||
if (task) {
|
||||
@ -124,11 +124,8 @@ static inline struct task_struct *__mutex_trylock_or_owner(struct mutex *lock)
|
||||
*/
|
||||
flags &= ~MUTEX_FLAG_HANDOFF;
|
||||
|
||||
old = atomic_long_cmpxchg_acquire(&lock->owner, owner, curr | flags);
|
||||
if (old == owner)
|
||||
if (atomic_long_try_cmpxchg_acquire(&lock->owner, &owner, curr | flags))
|
||||
return NULL;
|
||||
|
||||
owner = old;
|
||||
}
|
||||
|
||||
return __owner_task(owner);
|
||||
@ -168,10 +165,7 @@ static __always_inline bool __mutex_unlock_fast(struct mutex *lock)
|
||||
{
|
||||
unsigned long curr = (unsigned long)current;
|
||||
|
||||
if (atomic_long_cmpxchg_release(&lock->owner, curr, 0UL) == curr)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
return atomic_long_try_cmpxchg_release(&lock->owner, &curr, 0UL);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -216,7 +210,7 @@ static void __mutex_handoff(struct mutex *lock, struct task_struct *task)
|
||||
unsigned long owner = atomic_long_read(&lock->owner);
|
||||
|
||||
for (;;) {
|
||||
unsigned long old, new;
|
||||
unsigned long new;
|
||||
|
||||
#ifdef CONFIG_DEBUG_MUTEXES
|
||||
DEBUG_LOCKS_WARN_ON(__owner_task(owner) != current);
|
||||
@ -228,11 +222,8 @@ static void __mutex_handoff(struct mutex *lock, struct task_struct *task)
|
||||
if (task)
|
||||
new |= MUTEX_FLAG_PICKUP;
|
||||
|
||||
old = atomic_long_cmpxchg_release(&lock->owner, owner, new);
|
||||
if (old == owner)
|
||||
if (atomic_long_try_cmpxchg_release(&lock->owner, &owner, new))
|
||||
break;
|
||||
|
||||
owner = old;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1229,8 +1220,6 @@ static noinline void __sched __mutex_unlock_slowpath(struct mutex *lock, unsigne
|
||||
*/
|
||||
owner = atomic_long_read(&lock->owner);
|
||||
for (;;) {
|
||||
unsigned long old;
|
||||
|
||||
#ifdef CONFIG_DEBUG_MUTEXES
|
||||
DEBUG_LOCKS_WARN_ON(__owner_task(owner) != current);
|
||||
DEBUG_LOCKS_WARN_ON(owner & MUTEX_FLAG_PICKUP);
|
||||
@ -1239,16 +1228,12 @@ static noinline void __sched __mutex_unlock_slowpath(struct mutex *lock, unsigne
|
||||
if (owner & MUTEX_FLAG_HANDOFF)
|
||||
break;
|
||||
|
||||
old = atomic_long_cmpxchg_release(&lock->owner, owner,
|
||||
__owner_flags(owner));
|
||||
if (old == owner) {
|
||||
if (atomic_long_try_cmpxchg_release(&lock->owner, &owner, __owner_flags(owner))) {
|
||||
if (owner & MUTEX_FLAG_WAITERS)
|
||||
break;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
owner = old;
|
||||
}
|
||||
|
||||
spin_lock(&lock->wait_lock);
|
||||
|
Loading…
Reference in New Issue
Block a user