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;