svn commit: r325920 - head/sys/kern

Mateusz Guzik mjg at FreeBSD.org
Fri Nov 17 02:25:05 UTC 2017


Author: mjg
Date: Fri Nov 17 02:25:04 2017
New Revision: 325920
URL: https://svnweb.freebsd.org/changeset/base/325920

Log:
  mtx: unlock before traversing threads to wake up
  
  This shortens the lock hold time while not affecting corretness.
  All the woken up threads end up competing can lose the race against
  a completely unrelated thread getting the lock anyway.

Modified:
  head/sys/kern/kern_mutex.c

Modified: head/sys/kern/kern_mutex.c
==============================================================================
--- head/sys/kern/kern_mutex.c	Fri Nov 17 02:22:51 2017	(r325919)
+++ head/sys/kern/kern_mutex.c	Fri Nov 17 02:25:04 2017	(r325920)
@@ -629,7 +629,8 @@ __mtx_lock_sleep(volatile uintptr_t *c, uintptr_t v)
 #ifdef KDTRACE_HOOKS
 		sleep_time -= lockstat_nsecs(&m->lock_object);
 #endif
-		turnstile_wait(ts, mtx_owner(m), TS_EXCLUSIVE_QUEUE);
+		MPASS(owner == mtx_owner(m));
+		turnstile_wait(ts, owner, TS_EXCLUSIVE_QUEUE);
 #ifdef KDTRACE_HOOKS
 		sleep_time += lockstat_nsecs(&m->lock_object);
 		sleep_cnt++;
@@ -1002,7 +1003,7 @@ __mtx_unlock_sleep(volatile uintptr_t *c)
 {
 	struct mtx *m;
 	struct turnstile *ts;
-	uintptr_t tid, v;
+	uintptr_t tid;
 
 	if (SCHEDULER_STOPPED())
 		return;
@@ -1028,12 +1029,12 @@ __mtx_unlock_sleep(volatile uintptr_t *c)
 	 * can be removed from the hash list if it is empty.
 	 */
 	turnstile_chain_lock(&m->lock_object);
+	_mtx_release_lock_quick(m);
 	ts = turnstile_lookup(&m->lock_object);
+	MPASS(ts != NULL);
 	if (LOCK_LOG_TEST(&m->lock_object, opts))
 		CTR1(KTR_LOCK, "_mtx_unlock_sleep: %p contested", m);
-	MPASS(ts != NULL);
 	turnstile_broadcast(ts, TS_EXCLUSIVE_QUEUE);
-	_mtx_release_lock_quick(m);
 
 	/*
 	 * This turnstile is now no longer associated with the mutex.  We can


More information about the svn-src-all mailing list