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)) {