Module Name:    src
Committed By:   riastradh
Date:           Sat Apr  9 23:45:37 UTC 2022

Modified Files:
        src/sys/kern: kern_lwp.c kern_turnstile.c
        src/sys/sys: lwp.h

Log Message:
kern: Handle l_mutex with atomic_store_release, atomic_load_consume.

- Where the lock is held and known to be correct, no atomic.
- In loops to acquire the lock, use atomic_load_relaxed before we
  restart with atomic_load_consume.

Nix membar_exit.

(Who knows, using atomic_load_consume here might fix bugs on Alpha!)


To generate a diff of this commit:
cvs rdiff -u -r1.247 -r1.248 src/sys/kern/kern_lwp.c
cvs rdiff -u -r1.41 -r1.42 src/sys/kern/kern_turnstile.c
cvs rdiff -u -r1.214 -r1.215 src/sys/sys/lwp.h

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_lwp.c
diff -u src/sys/kern/kern_lwp.c:1.247 src/sys/kern/kern_lwp.c:1.248
--- src/sys/kern/kern_lwp.c:1.247	Thu Mar 10 12:21:25 2022
+++ src/sys/kern/kern_lwp.c	Sat Apr  9 23:45:36 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: kern_lwp.c,v 1.247 2022/03/10 12:21:25 riastradh Exp $	*/
+/*	$NetBSD: kern_lwp.c,v 1.248 2022/04/09 23:45:36 riastradh Exp $	*/
 
 /*-
  * Copyright (c) 2001, 2006, 2007, 2008, 2009, 2019, 2020
@@ -217,7 +217,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_lwp.c,v 1.247 2022/03/10 12:21:25 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_lwp.c,v 1.248 2022/04/09 23:45:36 riastradh Exp $");
 
 #include "opt_ddb.h"
 #include "opt_lockdebug.h"
@@ -1565,8 +1565,7 @@ lwp_setlock(struct lwp *l, kmutex_t *mtx
 
 	KASSERT(mutex_owned(oldmtx));
 
-	membar_exit();
-	l->l_mutex = mtx;
+	atomic_store_release(&l->l_mutex, mtx);
 	return oldmtx;
 }
 
@@ -1582,8 +1581,7 @@ lwp_unlock_to(struct lwp *l, kmutex_t *m
 	KASSERT(lwp_locked(l, NULL));
 
 	old = l->l_mutex;
-	membar_exit();
-	l->l_mutex = mtx;
+	atomic_store_release(&l->l_mutex, mtx);
 	mutex_spin_exit(old);
 }
 
@@ -1593,9 +1591,9 @@ lwp_trylock(struct lwp *l)
 	kmutex_t *old;
 
 	for (;;) {
-		if (!mutex_tryenter(old = l->l_mutex))
+		if (!mutex_tryenter(old = atomic_load_consume(&l->l_mutex)))
 			return 0;
-		if (__predict_true(l->l_mutex == old))
+		if (__predict_true(atomic_load_relaxed(&l->l_mutex) == old))
 			return 1;
 		mutex_spin_exit(old);
 	}

Index: src/sys/kern/kern_turnstile.c
diff -u src/sys/kern/kern_turnstile.c:1.41 src/sys/kern/kern_turnstile.c:1.42
--- src/sys/kern/kern_turnstile.c:1.41	Wed Feb 23 21:54:41 2022
+++ src/sys/kern/kern_turnstile.c	Sat Apr  9 23:45:36 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: kern_turnstile.c,v 1.41 2022/02/23 21:54:41 andvar Exp $	*/
+/*	$NetBSD: kern_turnstile.c,v 1.42 2022/04/09 23:45:36 riastradh Exp $	*/
 
 /*-
  * Copyright (c) 2002, 2006, 2007, 2009, 2019, 2020
@@ -61,7 +61,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_turnstile.c,v 1.41 2022/02/23 21:54:41 andvar Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_turnstile.c,v 1.42 2022/04/09 23:45:36 riastradh Exp $");
 
 #include <sys/param.h>
 #include <sys/lockdebug.h>
@@ -252,7 +252,7 @@ turnstile_lendpri(lwp_t *cur)
 		 * Because we already have another LWP lock (l->l_mutex) held,
 		 * we need to play a try lock dance to avoid deadlock.
 		 */
-		dolock = l->l_mutex != owner->l_mutex;
+		dolock = l->l_mutex != atomic_load_relaxed(&owner->l_mutex);
 		if (l == owner || (dolock && !lwp_trylock(owner))) {
 			/*
 			 * The owner was changed behind us or trylock failed.
@@ -299,7 +299,7 @@ turnstile_lendpri(lwp_t *cur)
 		l = owner;
 	}
 	LOCKDEBUG_BARRIER(l->l_mutex, 1);
-	if (cur->l_mutex != l->l_mutex) {
+	if (cur->l_mutex != atomic_load_relaxed(&l->l_mutex)) {
 		lwp_unlock(l);
 		lwp_lock(cur);
 	}
@@ -322,7 +322,8 @@ turnstile_unlendpri(turnstile_t *ts)
 
 	KASSERT(ts->ts_inheritor != NULL);
 	ts->ts_inheritor = NULL;
-	dolock = l->l_mutex == l->l_cpu->ci_schedstate.spc_lwplock;
+	dolock = (atomic_load_relaxed(&l->l_mutex) ==
+	    l->l_cpu->ci_schedstate.spc_lwplock);
 	if (dolock) {
 		lwp_lock(l);
 	}

Index: src/sys/sys/lwp.h
diff -u src/sys/sys/lwp.h:1.214 src/sys/sys/lwp.h:1.215
--- src/sys/sys/lwp.h:1.214	Sat Apr  9 13:38:15 2022
+++ src/sys/sys/lwp.h	Sat Apr  9 23:45:37 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: lwp.h,v 1.214 2022/04/09 13:38:15 riastradh Exp $	*/
+/*	$NetBSD: lwp.h,v 1.215 2022/04/09 23:45:37 riastradh Exp $	*/
 
 /*
  * Copyright (c) 2001, 2006, 2007, 2008, 2009, 2010, 2019, 2020
@@ -53,6 +53,7 @@ struct lwp;
 /* forward declare this for <machine/cpu.h> so it can get l_cpu. */
 static __inline struct cpu_info *lwp_getcpu(struct lwp *);
 #include <machine/cpu.h>		/* curcpu() and cpu_info */
+#include <sys/atomic.h>
 #ifdef _KERNEL_OPT
 #include "opt_kcov.h"
 #include "opt_kmsan.h"
@@ -407,16 +408,16 @@ void	lwp_whatis(uintptr_t, void (*)(cons
 static __inline void
 lwp_lock(lwp_t *l)
 {
-	kmutex_t *old = l->l_mutex;
+	kmutex_t *old = atomic_load_consume(&l->l_mutex);
 
 	/*
 	 * Note: mutex_spin_enter() will have posted a read barrier.
 	 * Re-test l->l_mutex.  If it has changed, we need to try again.
 	 */
 	mutex_spin_enter(old);
-	while (__predict_false(l->l_mutex != old)) {
+	while (__predict_false(atomic_load_relaxed(&l->l_mutex) != old)) {
 		mutex_spin_exit(old);
-		old = l->l_mutex;
+		old = atomic_load_consume(&l->l_mutex);
 		mutex_spin_enter(old);
 	}
 }

Reply via email to