Module Name:    src
Committed By:   ad
Date:           Mon Jan  6 11:12:56 UTC 2020

Modified Files:
        src/sys/kern: kern_mutex.c

Log Message:
mutex_vector_enter(): avoid some unneeded reads of mtx_owner.


To generate a diff of this commit:
cvs rdiff -u -r1.86 -r1.87 src/sys/kern/kern_mutex.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/kern/kern_mutex.c
diff -u src/sys/kern/kern_mutex.c:1.86 src/sys/kern/kern_mutex.c:1.87
--- src/sys/kern/kern_mutex.c:1.86	Wed Dec 11 20:46:06 2019
+++ src/sys/kern/kern_mutex.c	Mon Jan  6 11:12:55 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: kern_mutex.c,v 1.86 2019/12/11 20:46:06 ad Exp $	*/
+/*	$NetBSD: kern_mutex.c,v 1.87 2020/01/06 11:12:55 ad Exp $	*/
 
 /*-
  * Copyright (c) 2002, 2006, 2007, 2008, 2019 The NetBSD Foundation, Inc.
@@ -40,7 +40,7 @@
 #define	__MUTEX_PRIVATE
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_mutex.c,v 1.86 2019/12/11 20:46:06 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_mutex.c,v 1.87 2020/01/06 11:12:55 ad Exp $");
 
 #include <sys/param.h>
 #include <sys/atomic.h>
@@ -186,8 +186,8 @@ do {									\
 
 #define	MUTEX_OWNER(owner)						\
 	(owner & MUTEX_THREAD)
-#define	MUTEX_HAS_WAITERS(mtx)						\
-	(((int)(mtx)->mtx_owner & MUTEX_BIT_WAITERS) != 0)
+#define	MUTEX_HAS_WAITERS(owner)					\
+	((owner & MUTEX_BIT_WAITERS) != 0)
 
 #define	MUTEX_INITIALIZE_ADAPTIVE(mtx, dodebug)				\
 do {									\
@@ -209,10 +209,10 @@ do {									\
 	(mtx)->mtx_owner = MUTEX_THREAD;				\
 } while (/* CONSTCOND */ 0)
 
-#define	MUTEX_SPIN_P(mtx)		\
-    (((mtx)->mtx_owner & MUTEX_BIT_SPIN) != 0)
-#define	MUTEX_ADAPTIVE_P(mtx)		\
-    (((mtx)->mtx_owner & MUTEX_BIT_SPIN) == 0)
+#define	MUTEX_SPIN_P(owner)		\
+    (((owner) & MUTEX_BIT_SPIN) != 0)
+#define	MUTEX_ADAPTIVE_P(owner)		\
+    (((owner) & MUTEX_BIT_SPIN) == 0)
 
 #define	MUTEX_DEBUG_P(mtx)	(((mtx)->mtx_owner & MUTEX_BIT_NODEBUG) == 0)
 #if defined(LOCKDEBUG)
@@ -310,10 +310,11 @@ static void
 mutex_dump(const volatile void *cookie, lockop_printer_t pr)
 {
 	const volatile kmutex_t *mtx = cookie;
+	uintptr_t owner = mtx->mtx_owner;
 
 	pr("owner field  : %#018lx wait/spin: %16d/%d\n",
-	    (long)MUTEX_OWNER(mtx->mtx_owner), MUTEX_HAS_WAITERS(mtx),
-	    MUTEX_SPIN_P(mtx));
+	    (long)MUTEX_OWNER(owner), MUTEX_HAS_WAITERS(owner),
+	    MUTEX_SPIN_P(owner));
 }
 
 /*
@@ -327,7 +328,7 @@ static void __noinline
 mutex_abort(const char *func, size_t line, const kmutex_t *mtx, const char *msg)
 {
 
-	LOCKDEBUG_ABORT(func, line, mtx, (MUTEX_SPIN_P(mtx) ?
+	LOCKDEBUG_ABORT(func, line, mtx, (MUTEX_SPIN_P(mtx->mtx_owner) ?
 	    &mutex_spin_lockops : &mutex_adaptive_lockops), msg);
 }
 
@@ -380,10 +381,11 @@ mutex_init(kmutex_t *mtx, kmutex_type_t 
 void
 mutex_destroy(kmutex_t *mtx)
 {
+	uintptr_t owner = mtx->mtx_owner;
 
-	if (MUTEX_ADAPTIVE_P(mtx)) {
-		MUTEX_ASSERT(mtx, !MUTEX_OWNED(mtx->mtx_owner) &&
-		    !MUTEX_HAS_WAITERS(mtx));
+	if (MUTEX_ADAPTIVE_P(owner)) {
+		MUTEX_ASSERT(mtx, !MUTEX_OWNED(owner) &&
+		    !MUTEX_HAS_WAITERS(owner));
 	} else {
 		MUTEX_ASSERT(mtx, !MUTEX_SPINBIT_LOCKED_P(mtx));
 	}
@@ -454,7 +456,8 @@ mutex_vector_enter(kmutex_t *mtx)
 	/*
 	 * Handle spin mutexes.
 	 */
-	if (MUTEX_SPIN_P(mtx)) {
+	owner = mtx->mtx_owner;
+	if (MUTEX_SPIN_P(owner)) {
 #if defined(LOCKDEBUG) && defined(MULTIPROCESSOR)
 		u_int spins = 0;
 #endif
@@ -501,7 +504,7 @@ mutex_vector_enter(kmutex_t *mtx)
 
 	curthread = (uintptr_t)curlwp;
 
-	MUTEX_DASSERT(mtx, MUTEX_ADAPTIVE_P(mtx));
+	MUTEX_DASSERT(mtx, MUTEX_ADAPTIVE_P(owner));
 	MUTEX_ASSERT(mtx, curthread != 0);
 	MUTEX_ASSERT(mtx, !cpu_intr_p());
 	MUTEX_WANTLOCK(mtx);
@@ -519,7 +522,7 @@ mutex_vector_enter(kmutex_t *mtx)
 	 * then we stop spinning, and sleep instead.
 	 */
 	KPREEMPT_DISABLE(curlwp);
-	for (owner = mtx->mtx_owner;;) {
+	for (;;) {
 		if (!MUTEX_OWNED(owner)) {
 			/*
 			 * Mutex owner clear could mean two things:
@@ -667,12 +670,18 @@ mutex_vector_enter(kmutex_t *mtx)
 		 * If the waiters bit is not set it's unsafe to go asleep,
 		 * as we might never be awoken.
 		 */
-		if ((membar_consumer(), mutex_oncpu(owner)) ||
-		    (membar_consumer(), !MUTEX_HAS_WAITERS(mtx))) {
+		membar_consumer();
+		if (mutex_oncpu(owner)) {
 			turnstile_exit(mtx);
 			owner = mtx->mtx_owner;
 			continue;
 		}
+		membar_consumer();
+		owner = mtx->mtx_owner;
+		if (!MUTEX_HAS_WAITERS(owner)) {
+			turnstile_exit(mtx);
+			continue;
+		}
 #endif	/* MULTIPROCESSOR */
 
 		LOCKSTAT_START_TIMER(lsflag, slptime);
@@ -707,7 +716,7 @@ mutex_vector_exit(kmutex_t *mtx)
 	turnstile_t *ts;
 	uintptr_t curthread;
 
-	if (MUTEX_SPIN_P(mtx)) {
+	if (MUTEX_SPIN_P(mtx->mtx_owner)) {
 #ifdef FULL
 		if (__predict_false(!MUTEX_SPINBIT_LOCKED_P(mtx))) {
 			MUTEX_ABORT(mtx, "exiting unheld spin mutex");
@@ -748,7 +757,7 @@ mutex_vector_exit(kmutex_t *mtx)
 	 */
 	{
 		int s = splhigh();
-		if (!MUTEX_HAS_WAITERS(mtx)) {
+		if (!MUTEX_HAS_WAITERS(mtx->mtx_owner)) {
 			MUTEX_RELEASE(mtx);
 			splx(s);
 			return;
@@ -810,7 +819,7 @@ mutex_owned(const kmutex_t *mtx)
 
 	if (mtx == NULL)
 		return 0;
-	if (MUTEX_ADAPTIVE_P(mtx))
+	if (MUTEX_ADAPTIVE_P(mtx->mtx_owner))
 		return MUTEX_OWNER(mtx->mtx_owner) == (uintptr_t)curlwp;
 #ifdef FULL
 	return MUTEX_SPINBIT_LOCKED_P(mtx);
@@ -829,7 +838,7 @@ lwp_t *
 mutex_owner(const kmutex_t *mtx)
 {
 
-	MUTEX_ASSERT(mtx, MUTEX_ADAPTIVE_P(mtx));
+	MUTEX_ASSERT(mtx, MUTEX_ADAPTIVE_P(mtx->mtx_owner));
 	return (struct lwp *)MUTEX_OWNER(mtx->mtx_owner);
 }
 
@@ -846,7 +855,7 @@ mutex_owner_running(const kmutex_t *mtx)
 	uintptr_t owner;
 	bool rv;
 
-	MUTEX_ASSERT(mtx, MUTEX_ADAPTIVE_P(mtx));
+	MUTEX_ASSERT(mtx, MUTEX_ADAPTIVE_P(mtx->mtx_owner));
 	kpreempt_disable();
 	owner = mtx->mtx_owner;
 	rv = !MUTEX_OWNED(owner) || mutex_oncpu(MUTEX_OWNER(owner));
@@ -887,7 +896,7 @@ mutex_tryenter(kmutex_t *mtx)
 	/*
 	 * Handle spin mutexes.
 	 */
-	if (MUTEX_SPIN_P(mtx)) {
+	if (MUTEX_SPIN_P(mtx->mtx_owner)) {
 		MUTEX_SPIN_SPLRAISE(mtx);
 #ifdef FULL
 		if (MUTEX_SPINBIT_LOCK_TRY(mtx)) {

Reply via email to