Module Name: src
Committed By: ad
Date: Sat Feb 15 17:13:55 UTC 2020
Modified Files:
src/sys/compat/linux/common: linux_exec.c
src/sys/kern: kern_exec.c kern_lwp.c
src/sys/sys: lwp.h
Log Message:
PR kern/54922: 9.99.45@20200202 panic: diagnostic assertion linux ldconfig
triggers vpp != NULL in exit1()->radixtree.c line 674
Create an lwp_renumber() from the code in emulexec() and use in
linux_e_proc_exec() and linux_e_proc_fork() too.
To generate a diff of this commit:
cvs rdiff -u -r1.120 -r1.121 src/sys/compat/linux/common/linux_exec.c
cvs rdiff -u -r1.491 -r1.492 src/sys/kern/kern_exec.c
cvs rdiff -u -r1.225 -r1.226 src/sys/kern/kern_lwp.c
cvs rdiff -u -r1.200 -r1.201 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/compat/linux/common/linux_exec.c
diff -u src/sys/compat/linux/common/linux_exec.c:1.120 src/sys/compat/linux/common/linux_exec.c:1.121
--- src/sys/compat/linux/common/linux_exec.c:1.120 Fri Aug 10 21:44:58 2018
+++ src/sys/compat/linux/common/linux_exec.c Sat Feb 15 17:13:55 2020
@@ -1,7 +1,8 @@
-/* $NetBSD: linux_exec.c,v 1.120 2018/08/10 21:44:58 pgoyette Exp $ */
+/* $NetBSD: linux_exec.c,v 1.121 2020/02/15 17:13:55 ad Exp $ */
/*-
- * Copyright (c) 1994, 1995, 1998, 2000, 2007, 2008 The NetBSD Foundation, Inc.
+ * Copyright (c) 1994, 1995, 1998, 2000, 2007, 2008, 2020
+ * The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
@@ -31,11 +32,12 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: linux_exec.c,v 1.120 2018/08/10 21:44:58 pgoyette Exp $");
+__KERNEL_RCSID(0, "$NetBSD: linux_exec.c,v 1.121 2020/02/15 17:13:55 ad Exp $");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
+#include <sys/lwp.h>
#include <sys/proc.h>
#include <sys/namei.h>
#include <sys/vnode.h>
@@ -129,9 +131,7 @@ linux_e_proc_exec(struct proc *p, struct
KASSERT(p->p_nlwps == 1);
l = LIST_FIRST(&p->p_lwps);
- mutex_enter(p->p_lock);
- l->l_lid = p->p_pid;
- mutex_exit(p->p_lock);
+ lwp_renumber(l, p->p_pid);
}
void
@@ -152,7 +152,7 @@ linux_e_proc_fork(struct proc *p2, struc
KASSERT(p2->p_nlwps == 1);
l2 = LIST_FIRST(&p2->p_lwps);
- l2->l_lid = p2->p_pid;
+ lwp_renumber(l2, p2->p_pid);
led1 = l1->l_emuldata;
led2 = l2->l_emuldata;
led2->led_child_tidptr = led1->led_child_tidptr;
Index: src/sys/kern/kern_exec.c
diff -u src/sys/kern/kern_exec.c:1.491 src/sys/kern/kern_exec.c:1.492
--- src/sys/kern/kern_exec.c:1.491 Mon Feb 10 22:13:01 2020
+++ src/sys/kern/kern_exec.c Sat Feb 15 17:13:55 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: kern_exec.c,v 1.491 2020/02/10 22:13:01 christos Exp $ */
+/* $NetBSD: kern_exec.c,v 1.492 2020/02/15 17:13:55 ad Exp $ */
/*-
* Copyright (c) 2008, 2019 The NetBSD Foundation, Inc.
@@ -62,7 +62,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_exec.c,v 1.491 2020/02/10 22:13:01 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_exec.c,v 1.492 2020/02/15 17:13:55 ad Exp $");
#include "opt_exec.h"
#include "opt_execfmt.h"
@@ -1148,32 +1148,9 @@ emulexec(struct lwp *l, struct exec_pack
&& p->p_emul != epp->ep_esch->es_emul)
(*p->p_emul->e_proc_exit)(p);
- /*
- * This is now LWP 1. Re-number the LWP if needed. Don't bother
- * with p_treelock here as this is the only live LWP in the proc
- * right now.
- */
- while (__predict_false(l->l_lid != 1)) {
- lwp_t *l2 __diagused;
- int error;
-
- mutex_enter(p->p_lock);
- error = radix_tree_insert_node(&p->p_lwptree, 1 - 1, l);
- if (error == 0) {
- l2 = radix_tree_remove_node(&p->p_lwptree,
- (uint64_t)(l->l_lid - 1));
- KASSERT(l2 == l);
- p->p_nlwpid = 2;
- l->l_lid = 1;
- }
- mutex_exit(p->p_lock);
-
- if (error == 0)
- break;
-
- KASSERT(error == ENOMEM);
- radix_tree_await_memory();
- }
+ /* This is now LWP 1. Re-number the LWP if needed. */
+ if (l->l_lid != 1)
+ lwp_renumber(l, 1);
/*
* Call exec hook. Emulation code may NOT store reference to anything
Index: src/sys/kern/kern_lwp.c
diff -u src/sys/kern/kern_lwp.c:1.225 src/sys/kern/kern_lwp.c:1.226
--- src/sys/kern/kern_lwp.c:1.225 Tue Feb 11 06:09:48 2020
+++ src/sys/kern/kern_lwp.c Sat Feb 15 17:13:55 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: kern_lwp.c,v 1.225 2020/02/11 06:09:48 dogcow Exp $ */
+/* $NetBSD: kern_lwp.c,v 1.226 2020/02/15 17:13: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.225 2020/02/11 06:09:48 dogcow Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_lwp.c,v 1.226 2020/02/15 17:13:55 ad Exp $");
#include "opt_ddb.h"
#include "opt_lockdebug.h"
@@ -2025,6 +2025,40 @@ lwp_setprivate(struct lwp *l, void *ptr)
return error;
}
+/*
+ * Renumber the first and only LWP in a process on exec() or fork().
+ * Don't bother with p_treelock here as this is the only live LWP in
+ * the proc right now.
+ */
+void
+lwp_renumber(lwp_t *l, lwpid_t lid)
+{
+ lwp_t *l2 __diagused;
+ proc_t *p = l->l_proc;
+ int error;
+
+ KASSERT(p->p_nlwps == 1);
+
+ while (l->l_lid != lid) {
+ mutex_enter(p->p_lock);
+ error = radix_tree_insert_node(&p->p_lwptree, lid - 1, l);
+ if (error == 0) {
+ l2 = radix_tree_remove_node(&p->p_lwptree,
+ (uint64_t)(l->l_lid - 1));
+ KASSERT(l2 == l);
+ p->p_nlwpid = lid + 1;
+ l->l_lid = lid;
+ }
+ mutex_exit(p->p_lock);
+
+ if (error == 0)
+ break;
+
+ KASSERT(error == ENOMEM);
+ radix_tree_await_memory();
+ }
+}
+
#if defined(DDB)
#include <machine/pcb.h>
Index: src/sys/sys/lwp.h
diff -u src/sys/sys/lwp.h:1.200 src/sys/sys/lwp.h:1.201
--- src/sys/sys/lwp.h:1.200 Wed Jan 29 15:47:52 2020
+++ src/sys/sys/lwp.h Sat Feb 15 17:13:55 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: lwp.h,v 1.200 2020/01/29 15:47:52 ad Exp $ */
+/* $NetBSD: lwp.h,v 1.201 2020/02/15 17:13:55 ad Exp $ */
/*
* Copyright (c) 2001, 2006, 2007, 2008, 2009, 2010, 2019, 2020
@@ -334,6 +334,7 @@ void lwp_drainrefs(lwp_t *);
bool lwp_alive(lwp_t *);
lwp_t *lwp_find_first(proc_t *);
+void lwp_renumber(lwp_t *, lwpid_t);
int lwp_wait(lwp_t *, lwpid_t, lwpid_t *, bool);
void lwp_continue(lwp_t *);
void lwp_unsleep(lwp_t *, bool);