[RFC PATCH 1/3] locking/mutex: Try to acquire mutex only if it is unlocked

From: Jason Low
Date: Wed Jun 04 2014 - 15:10:19 EST


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.low2@xxxxxx>
---
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 majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/