Index: sys/lwp.h =================================================================== RCS file: /cvsroot/src/sys/sys/lwp.h,v retrieving revision 1.200 diff -u -p -r1.200 lwp.h --- sys/lwp.h 29 Jan 2020 15:47:52 -0000 1.200 +++ sys/lwp.h 8 Feb 2020 20:10:04 -0000 @@ -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); Index: kern/kern_exec.c =================================================================== RCS file: /cvsroot/src/sys/kern/kern_exec.c,v retrieving revision 1.490 diff -u -p -r1.490 kern_exec.c --- kern/kern_exec.c 29 Jan 2020 15:47:52 -0000 1.490 +++ kern/kern_exec.c 8 Feb 2020 20:10:04 -0000 @@ -1140,32 +1140,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: kern/kern_lwp.c =================================================================== RCS file: /cvsroot/src/sys/kern/kern_lwp.c,v retrieving revision 1.223 diff -u -p -r1.223 kern_lwp.c --- kern/kern_lwp.c 29 Jan 2020 15:47:52 -0000 1.223 +++ kern/kern_lwp.c 8 Feb 2020 20:10:04 -0000 @@ -2022,6 +2022,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 Index: compat/linux/common/linux_exec.c =================================================================== RCS file: /cvsroot/src/sys/compat/linux/common/linux_exec.c,v retrieving revision 1.120 diff -u -p -r1.120 linux_exec.c --- compat/linux/common/linux_exec.c 10 Aug 2018 21:44:58 -0000 1.120 +++ compat/linux/common/linux_exec.c 8 Feb 2020 20:10:04 -0000 @@ -1,7 +1,8 @@ /* $NetBSD: linux_exec.c,v 1.120 2018/08/10 21:44:58 pgoyette 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 @@ -36,6 +37,7 @@ __KERNEL_RCSID(0, "$NetBSD: linux_exec.c #include #include #include +#include #include #include #include @@ -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;