Module Name:    src
Committed By:   ad
Date:           Sat May 30 19:16:53 UTC 2020

Modified Files:
        src/sys/rump/librump/rumpkern: lwproc.c

Log Message:
Fix a lock order reversal that caused hangs.


To generate a diff of this commit:
cvs rdiff -u -r1.50 -r1.51 src/sys/rump/librump/rumpkern/lwproc.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/rump/librump/rumpkern/lwproc.c
diff -u src/sys/rump/librump/rumpkern/lwproc.c:1.50 src/sys/rump/librump/rumpkern/lwproc.c:1.51
--- src/sys/rump/librump/rumpkern/lwproc.c:1.50	Sat May 23 23:42:44 2020
+++ src/sys/rump/librump/rumpkern/lwproc.c	Sat May 30 19:16:53 2020
@@ -1,4 +1,4 @@
-/*      $NetBSD: lwproc.c,v 1.50 2020/05/23 23:42:44 ad Exp $	*/
+/*      $NetBSD: lwproc.c,v 1.51 2020/05/30 19:16:53 ad Exp $	*/
 
 /*
  * Copyright (c) 2010, 2011 Antti Kantee.  All Rights Reserved.
@@ -28,7 +28,7 @@
 #define RUMP__CURLWP_PRIVATE
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: lwproc.c,v 1.50 2020/05/23 23:42:44 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: lwproc.c,v 1.51 2020/05/30 19:16:53 ad Exp $");
 
 #include <sys/param.h>
 #include <sys/atomic.h>
@@ -343,12 +343,10 @@ lwproc_freelwp(struct lwp *l)
 
 extern kmutex_t unruntime_lock;
 
-/*
- * called with p_lock held, releases lock before return
- */
-static void
-lwproc_makelwp(struct proc *p, struct lwp *l, bool doswitch, bool procmake)
+static struct lwp *
+lwproc_makelwp(struct proc *p, bool doswitch, bool procmake)
 {
+	struct lwp *l = kmem_zalloc(sizeof(*l), KM_SLEEP);
 
 	/*
 	 * Account the new lwp to the owner of the process.
@@ -365,6 +363,9 @@ lwproc_makelwp(struct proc *p, struct lw
 	l->l_mutex = &unruntime_lock;
 
 	proc_alloc_lwpid(p, l);
+
+	mutex_enter(p->p_lock);
+	KASSERT((p->p_sflag & PS_RUMP_LWPEXIT) == 0);
 	LIST_INSERT_HEAD(&p->p_lwps, l, l_sibling);
 
 	l->l_fd = p->p_fd;
@@ -392,12 +393,13 @@ lwproc_makelwp(struct proc *p, struct lw
 	mutex_enter(&proc_lock);
 	LIST_INSERT_HEAD(&alllwp, l, l_list);
 	mutex_exit(&proc_lock);
+
+	return l;
 }
 
 struct lwp *
 rump__lwproc_alloclwp(struct proc *p)
 {
-	struct lwp *l;
 	bool newproc = false;
 
 	if (p == NULL) {
@@ -405,13 +407,7 @@ rump__lwproc_alloclwp(struct proc *p)
 		newproc = true;
 	}
 
-	l = kmem_zalloc(sizeof(*l), KM_SLEEP);
-
-	mutex_enter(p->p_lock);
-	KASSERT((p->p_sflag & PS_RUMP_LWPEXIT) == 0);
-	lwproc_makelwp(p, l, false, newproc);
-
-	return l;
+	return lwproc_makelwp(p, false, newproc);
 }
 
 int
@@ -435,8 +431,12 @@ rump_lwproc_newlwp(pid_t pid)
 		kmem_free(l, sizeof(*l));
 		return EBUSY;
 	}
+	mutex_exit(p->p_lock);
 	mutex_exit(&proc_lock);
-	lwproc_makelwp(p, l, true, false);
+
+	/* XXX what holds proc? */
+
+	lwproc_makelwp(p, true, false);
 
 	return 0;
 }
@@ -445,17 +445,13 @@ int
 rump_lwproc_rfork_vmspace(struct vmspace *vm, int flags)
 {
 	struct proc *p;
-	struct lwp *l;
 
 	if (flags & ~(RUMP_RFFDG|RUMP_RFCFDG) ||
 	    (~flags & (RUMP_RFFDG|RUMP_RFCFDG)) == 0)
 		return EINVAL;
 
 	p = lwproc_newproc(curproc, vm, flags);
-	l = kmem_zalloc(sizeof(*l), KM_SLEEP);
-	mutex_enter(p->p_lock);
-	KASSERT((p->p_sflag & PS_RUMP_LWPEXIT) == 0);
-	lwproc_makelwp(p, l, true, true);
+	lwproc_makelwp(p, true, true);
 
 	return 0;
 }

Reply via email to