Module Name:    src
Committed By:   martin
Date:           Sat Mar 10 08:46:46 UTC 2012

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

Log Message:
Make sure the child of a posix_spawn operation is not preempted during
the times when it does not have any vm_space.
Should fix PR kern/46153.


To generate a diff of this commit:
cvs rdiff -u -r1.344 -r1.345 src/sys/kern/kern_exec.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/kern_exec.c
diff -u src/sys/kern/kern_exec.c:1.344 src/sys/kern/kern_exec.c:1.345
--- src/sys/kern/kern_exec.c:1.344	Tue Feb 21 04:13:22 2012
+++ src/sys/kern/kern_exec.c	Sat Mar 10 08:46:45 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: kern_exec.c,v 1.344 2012/02/21 04:13:22 christos Exp $	*/
+/*	$NetBSD: kern_exec.c,v 1.345 2012/03/10 08:46:45 martin Exp $	*/
 
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -59,7 +59,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_exec.c,v 1.344 2012/02/21 04:13:22 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_exec.c,v 1.345 2012/03/10 08:46:45 martin Exp $");
 
 #include "opt_exec.h"
 #include "opt_ktrace.h"
@@ -1739,11 +1739,13 @@ spawn_return(void *arg)
 	register_t retval;
 	bool have_reflock;
 
+	/* we have been created non-preemptable */
+	KASSERT(l->l_nopreempt == 1);
+
 	/*
 	 * The following actions may block, so we need a temporary
 	 * vmspace - borrow the kernel one
 	 */
-	KPREEMPT_DISABLE(l);
 	l->l_proc->p_vmspace = proc0.p_vmspace;
 	pmap_activate(l);
 	KPREEMPT_ENABLE(l);
@@ -1869,8 +1871,6 @@ spawn_return(void *arg)
 	KPREEMPT_DISABLE(l);
 	pmap_deactivate(l);
 	l->l_proc->p_vmspace = NULL;
-	KPREEMPT_ENABLE(l);
-
 
 	/* now do the real exec */
 	rw_enter(&exec_lock, RW_READER);
@@ -1881,6 +1881,9 @@ spawn_return(void *arg)
 	else if (error)
 		goto report_error;
 
+	/* we now have our own vmspace */
+	KPREEMPT_ENABLE(l);
+
 	/* done, signal parent */
 	mutex_enter(&spawn_data->sed_mtx_child);
 	cv_signal(&spawn_data->sed_cv_child_ready);
@@ -2230,6 +2233,8 @@ sys_posix_spawn(struct lwp *l1, const st
 		kauth_cred_free(ocred);
 	}
 
+	l2->l_nopreempt = 1; /* start it non-preemptable */
+
 	/*
 	 * It's now safe for the scheduler and other processes to see the
 	 * child process.

Reply via email to