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);

Reply via email to