Upon entering the slowpath in __mutex_lock_common(), we try once more to acquire the mutex. We only try to acquire it if MUTEX_SHOW_NO_WAITER (lock->count >= 0) is true in order to avoid using the atomic xchg() operation whenever it is not necessary. However, we really only need to try to acquire if the mutex is free (lock->count == 1).
This patch changes it so that we only try-acquire the mutex upon entering the slowpath if it is unlocked, rather than if there are no waiters. This helps further reduce unncessary atomic xchg() operations. Furthermore, this patch introduces and uses a new MUTEX_IS_UNLOCKED() macro to improve readbability. Signed-off-by: Jason Low <jason.l...@hp.com> --- kernel/locking/mutex.c | 10 ++++++---- 1 files changed, 6 insertions(+), 4 deletions(-) diff --git a/kernel/locking/mutex.c b/kernel/locking/mutex.c index bc73d33..0925968 100644 --- a/kernel/locking/mutex.c +++ b/kernel/locking/mutex.c @@ -48,9 +48,10 @@ /* * A negative mutex count indicates that waiters are sleeping waiting for the - * mutex. + * mutex, and a count of one indicates the mutex is unlocked. */ #define MUTEX_SHOW_NO_WAITER(mutex) (atomic_read(&(mutex)->count) >= 0) +#define MUTEX_IS_UNLOCKED(mutex) (atomic_read(&(mutex)->count) == 1) void __mutex_init(struct mutex *lock, const char *name, struct lock_class_key *key) @@ -440,7 +441,8 @@ __mutex_lock_common(struct mutex *lock, long state, unsigned int subclass, if (owner && !mutex_spin_on_owner(lock, owner)) break; - if ((atomic_read(&lock->count) == 1) && + /* Try to acquire the lock if it is free. */ + if (MUTEX_IS_UNLOCKED(lock) && (atomic_cmpxchg(&lock->count, 1, 0) == 1)) { lock_acquired(&lock->dep_map, ip); if (use_ww_ctx) { @@ -485,8 +487,8 @@ slowpath: #endif spin_lock_mutex(&lock->wait_lock, flags); - /* once more, can we acquire the lock? */ - if (MUTEX_SHOW_NO_WAITER(lock) && (atomic_xchg(&lock->count, 0) == 1)) + /* once more, try to acquire the lock if it is free: */ + if (MUTEX_IS_UNLOCKED(lock) && (atomic_xchg(&lock->count, 0) == 1)) goto skip_wait; debug_mutex_lock_common(lock, &waiter); -- 1.7.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/