Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/kern Fix crash observed with procfs on current-users by ...
details: https://anonhg.NetBSD.org/src/rev/77c644c639ca
branches: trunk
changeset: 1008564:77c644c639ca
user: ad <ad%NetBSD.org@localhost>
date: Thu Mar 26 21:31:55 2020 +0000
description:
Fix crash observed with procfs on current-users by David Hopper. LWP refcnt
and p_zomblwp both must reach the needed state, and LSZOMB be set, under a
single hold of p_lock.
diffstat:
sys/kern/kern_exit.c | 8 +++++---
sys/kern/kern_lwp.c | 40 +++++++++++++++++++++++-----------------
2 files changed, 28 insertions(+), 20 deletions(-)
diffs (130 lines):
diff -r 7d7cc8d16aa3 -r 77c644c639ca sys/kern/kern_exit.c
--- a/sys/kern/kern_exit.c Thu Mar 26 21:25:26 2020 +0000
+++ b/sys/kern/kern_exit.c Thu Mar 26 21:31:55 2020 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: kern_exit.c,v 1.285 2020/03/08 15:05:18 ad Exp $ */
+/* $NetBSD: kern_exit.c,v 1.286 2020/03/26 21:31:55 ad Exp $ */
/*-
* Copyright (c) 1998, 1999, 2006, 2007, 2008, 2020 The NetBSD Foundation, Inc.
@@ -67,7 +67,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_exit.c,v 1.285 2020/03/08 15:05:18 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_exit.c,v 1.286 2020/03/26 21:31:55 ad Exp $");
#include "opt_ktrace.h"
#include "opt_dtrace.h"
@@ -559,7 +559,9 @@
/* Free the linux lwp id */
if ((l->l_pflag & LP_PIDLID) != 0 && l->l_lid != p->p_pid)
proc_free_pid(l->l_lid);
- lwp_drainrefs(l);
+ if (l->l_refcnt > 0) {
+ lwp_drainrefs(l);
+ }
lwp_lock(l);
l->l_prflag &= ~LPR_DETACHED;
l->l_stat = LSZOMB;
diff -r 7d7cc8d16aa3 -r 77c644c639ca sys/kern/kern_lwp.c
--- a/sys/kern/kern_lwp.c Thu Mar 26 21:25:26 2020 +0000
+++ b/sys/kern/kern_lwp.c Thu Mar 26 21:31:55 2020 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: kern_lwp.c,v 1.230 2020/03/26 20:19:06 ad Exp $ */
+/* $NetBSD: kern_lwp.c,v 1.231 2020/03/26 21:31:55 ad Exp $ */
/*-
* Copyright (c) 2001, 2006, 2007, 2008, 2009, 2019, 2020
@@ -211,7 +211,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_lwp.c,v 1.230 2020/03/26 20:19:06 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_lwp.c,v 1.231 2020/03/26 21:31:55 ad Exp $");
#include "opt_ddb.h"
#include "opt_lockdebug.h"
@@ -274,7 +274,7 @@
.l_stat = LSONPROC,
.l_ts = &turnstile0,
.l_syncobj = &sched_syncobj,
- .l_refcnt = 1,
+ .l_refcnt = 0,
.l_priority = PRI_USER + NPRI_USER - 1,
.l_inheritedprio = -1,
.l_class = SCHED_OTHER,
@@ -821,7 +821,7 @@
l2->l_stat = LSIDL;
l2->l_proc = p2;
- l2->l_refcnt = 1;
+ l2->l_refcnt = 0;
l2->l_class = sclass;
/*
@@ -1180,19 +1180,27 @@
* mark it waiting for collection in the proc structure. Note that
* before we can do that, we need to free any other dead, deatched
* LWP waiting to meet its maker.
+ *
+ * All conditions need to be observed upon under the same hold of
+ * p_lock, because if the lock is dropped any of them can change.
*/
mutex_enter(p->p_lock);
- lwp_drainrefs(l);
-
- if ((l->l_prflag & LPR_DETACHED) != 0) {
- while ((l2 = p->p_zomblwp) != NULL) {
- p->p_zomblwp = NULL;
- lwp_free(l2, false, false);/* releases proc mutex */
- mutex_enter(p->p_lock);
- l->l_refcnt++;
+ for (;;) {
+ if (l->l_refcnt > 0) {
lwp_drainrefs(l);
+ continue;
}
- p->p_zomblwp = l;
+ if ((l->l_prflag & LPR_DETACHED) != 0) {
+ if ((l2 = p->p_zomblwp) != NULL) {
+ p->p_zomblwp = NULL;
+ lwp_free(l2, false, false);
+ /* proc now unlocked */
+ mutex_enter(p->p_lock);
+ continue;
+ }
+ p->p_zomblwp = l;
+ }
+ break;
}
/*
@@ -1692,7 +1700,6 @@
KASSERT(mutex_owned(l->l_proc->p_lock));
KASSERT(l->l_stat != LSZOMB);
- KASSERT(l->l_refcnt != 0);
l->l_refcnt++;
}
@@ -1724,6 +1731,7 @@
KASSERT(mutex_owned(p->p_lock));
KASSERT(l->l_stat != LSZOMB);
KASSERT(l->l_refcnt > 0);
+
if (--l->l_refcnt == 0)
cv_broadcast(&p->p_lwpcv);
}
@@ -1737,10 +1745,8 @@
struct proc *p = l->l_proc;
KASSERT(mutex_owned(p->p_lock));
- KASSERT(l->l_refcnt != 0);
- l->l_refcnt--;
- while (l->l_refcnt != 0)
+ while (l->l_refcnt > 0)
cv_wait(&p->p_lwpcv, p->p_lock);
}
Home |
Main Index |
Thread Index |
Old Index