Module Name:    src
Committed By:   skrll
Date:           Sun Jun  6 07:46:18 UTC 2010

Modified Files:
        src/sys/kern: sys_lwp.c

Log Message:
Follow the correct locking protocol when creating an LWP and the process
is stopping.

Problem found by running the gdb testsuite (gdb didn't have pthreads
support)

Thanks to rmind for help with this.


To generate a diff of this commit:
cvs rdiff -u -r1.49 -r1.50 src/sys/kern/sys_lwp.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/kern/sys_lwp.c
diff -u src/sys/kern/sys_lwp.c:1.49 src/sys/kern/sys_lwp.c:1.50
--- src/sys/kern/sys_lwp.c:1.49	Fri Apr 23 19:18:09 2010
+++ src/sys/kern/sys_lwp.c	Sun Jun  6 07:46:17 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: sys_lwp.c,v 1.49 2010/04/23 19:18:09 rmind Exp $	*/
+/*	$NetBSD: sys_lwp.c,v 1.50 2010/06/06 07:46:17 skrll Exp $	*/
 
 /*-
  * Copyright (c) 2001, 2006, 2007, 2008 The NetBSD Foundation, Inc.
@@ -35,7 +35,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sys_lwp.c,v 1.49 2010/04/23 19:18:09 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sys_lwp.c,v 1.50 2010/06/06 07:46:17 skrll Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -82,6 +82,7 @@
 	} */
 	struct proc *p = l->l_proc;
 	struct lwp *l2;
+	struct schedstate_percpu *spc;
 	vaddr_t uaddr;
 	ucontext_t *newuc;
 	int error, lid;
@@ -133,20 +134,23 @@
 	 */
 	mutex_enter(p->p_lock);
 	lwp_lock(l2);
+	spc = &l2->l_cpu->ci_schedstate;
 	if ((SCARG(uap, flags) & LWP_SUSPENDED) == 0 &&
 	    (l->l_flag & (LW_WREBOOT | LW_WSUSPEND | LW_WEXIT)) == 0) {
-	    	if (p->p_stat == SSTOP || (p->p_sflag & PS_STOPPING) != 0)
+	    	if (p->p_stat == SSTOP || (p->p_sflag & PS_STOPPING) != 0) {
+			KASSERT(l2->l_wchan == NULL);
 	    		l2->l_stat = LSSTOP;
-		else {
-			KASSERT(lwp_locked(l2, l2->l_cpu->ci_schedstate.spc_mutex));
+			lwp_unlock_to(l2, spc->spc_lwplock);
+		} else {
+			KASSERT(lwp_locked(l2, spc->spc_mutex));
 			p->p_nrlwps++;
 			l2->l_stat = LSRUN;
 			sched_enqueue(l2, false);
+			lwp_unlock(l2);
 		}
-		lwp_unlock(l2);
 	} else {
 		l2->l_stat = LSSUSPENDED;
-		lwp_unlock_to(l2, l2->l_cpu->ci_schedstate.spc_lwplock);
+		lwp_unlock_to(l2, spc->spc_lwplock);
 	}
 	mutex_exit(p->p_lock);
 

Reply via email to