Module Name:    src
Committed By:   ad
Date:           Thu Nov 21 18:17:36 UTC 2019

Modified Files:
        src/sys/kern: kern_lwp.c kern_sig.c

Log Message:
- lwp_need_userret(): only do it if ONPROC and !curlwp, and explain why.
- Use signotify() in a couple more places.


To generate a diff of this commit:
cvs rdiff -u -r1.208 -r1.209 src/sys/kern/kern_lwp.c
cvs rdiff -u -r1.379 -r1.380 src/sys/kern/kern_sig.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_lwp.c
diff -u src/sys/kern/kern_lwp.c:1.208 src/sys/kern/kern_lwp.c:1.209
--- src/sys/kern/kern_lwp.c:1.208	Thu Nov 14 16:23:52 2019
+++ src/sys/kern/kern_lwp.c	Thu Nov 21 18:17:36 2019
@@ -1,7 +1,7 @@
-/*	$NetBSD: kern_lwp.c,v 1.208 2019/11/14 16:23:52 maxv Exp $	*/
+/*	$NetBSD: kern_lwp.c,v 1.209 2019/11/21 18:17:36 ad Exp $	*/
 
 /*-
- * Copyright (c) 2001, 2006, 2007, 2008, 2009 The NetBSD Foundation, Inc.
+ * Copyright (c) 2001, 2006, 2007, 2008, 2009, 2019 The NetBSD Foundation, Inc.
  * All rights reserved.
  *
  * This code is derived from software contributed to The NetBSD Foundation
@@ -211,7 +211,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_lwp.c,v 1.208 2019/11/14 16:23:52 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_lwp.c,v 1.209 2019/11/21 18:17:36 ad Exp $");
 
 #include "opt_ddb.h"
 #include "opt_lockdebug.h"
@@ -1147,7 +1147,7 @@ lwp_exit(struct lwp *l)
 	    firstsig(&p->p_sigpend.sp_set) != 0) {
 		LIST_FOREACH(l2, &p->p_lwps, l_sibling) {
 			lwp_lock(l2);
-			l2->l_flag |= LW_PENDSIG;
+			signotify(l2);
 			lwp_unlock(l2);
 		}
 	}
@@ -1616,15 +1616,26 @@ lwp_userret(struct lwp *l)
 void
 lwp_need_userret(struct lwp *l)
 {
+
+	KASSERT(!cpu_intr_p());
 	KASSERT(lwp_locked(l, NULL));
 
 	/*
-	 * Since the tests in lwp_userret() are done unlocked, make sure
-	 * that the condition will be seen before forcing the LWP to enter
-	 * kernel mode.
-	 */
-	membar_producer();
-	cpu_signotify(l);
+	 * If the LWP is in any state other than LSONPROC, we know that it
+	 * is executing in-kernel and will hit userret() on the way out. 
+	 *
+	 * If the LWP is curlwp, then we know we'll be back out to userspace
+	 * soon (can't be called from a hardware interrupt here).
+	 *
+	 * Otherwise, we can't be sure what the LWP is doing, so first make
+	 * sure the update to l_flag will be globally visible, and then
+	 * force the LWP to take a trip through trap() where it will do
+	 * userret().
+	 */
+	if (l->l_stat == LSONPROC && l != curlwp) {
+		membar_producer();
+		cpu_signotify(l);
+	}
 }
 
 /*

Index: src/sys/kern/kern_sig.c
diff -u src/sys/kern/kern_sig.c:1.379 src/sys/kern/kern_sig.c:1.380
--- src/sys/kern/kern_sig.c:1.379	Wed Nov 20 19:37:53 2019
+++ src/sys/kern/kern_sig.c	Thu Nov 21 18:17:36 2019
@@ -1,7 +1,7 @@
-/*	$NetBSD: kern_sig.c,v 1.379 2019/11/20 19:37:53 pgoyette Exp $	*/
+/*	$NetBSD: kern_sig.c,v 1.380 2019/11/21 18:17:36 ad Exp $	*/
 
 /*-
- * Copyright (c) 2006, 2007, 2008 The NetBSD Foundation, Inc.
+ * Copyright (c) 2006, 2007, 2008, 2019 The NetBSD Foundation, Inc.
  * All rights reserved.
  *
  * This code is derived from software contributed to The NetBSD Foundation
@@ -70,7 +70,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_sig.c,v 1.379 2019/11/20 19:37:53 pgoyette Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_sig.c,v 1.380 2019/11/21 18:17:36 ad Exp $");
 
 #include "opt_ptrace.h"
 #include "opt_dtrace.h"
@@ -710,6 +710,9 @@ sigclearall(struct proc *p, const sigset
  *	current LWP.  May be called unlocked provided that LW_PENDSIG is set,
  *	and that the signal has been posted to the appopriate queue before
  *	LW_PENDSIG is set.
+ *
+ *	This should only ever be called with (l == curlwp), unless the
+ *	result does not matter (procfs, sysctl).
  */ 
 int
 sigispending(struct lwp *l, int signo)
@@ -1133,7 +1136,7 @@ sigpost(struct lwp *l, sig_t action, int
 	 * Have the LWP check for signals.  This ensures that even if no LWP
 	 * is found to take the signal immediately, it should be taken soon.
 	 */
-	l->l_flag |= LW_PENDSIG;
+	signotify(l);
 
 	/*
 	 * SIGCONT can be masked, but if LWP is stopped, it needs restart.
@@ -1167,7 +1170,6 @@ sigpost(struct lwp *l, sig_t action, int
 	switch (l->l_stat) {
 	case LSRUN:
 	case LSONPROC:
-		lwp_need_userret(l);
 		rv = 1;
 		break;
 

Reply via email to