summaryrefslogtreecommitdiffstats
path: root/sys/kern
diff options
context:
space:
mode:
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/kern_exit.c33
-rw-r--r--sys/kern/kern_fork.c8
2 files changed, 30 insertions, 11 deletions
diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c
index 8022cb5..812b20e 100644
--- a/sys/kern/kern_exit.c
+++ b/sys/kern/kern_exit.c
@@ -54,6 +54,7 @@
#include <sys/tty.h>
#include <sys/wait.h>
#include <sys/vnode.h>
+#include <sys/vmmeter.h>
#include <sys/resourcevar.h>
#include <sys/signalvar.h>
#include <sys/sx.h>
@@ -67,6 +68,7 @@
#include <vm/vm.h>
#include <vm/vm_param.h>
+#include <vm/vm_extern.h>
#include <vm/pmap.h>
#include <vm/vm_map.h>
#include <vm/vm_zone.h>
@@ -380,13 +382,30 @@ exit1(p, rv)
/*
* Finally, call machine-dependent code to release the remaining
* resources including address space, the kernel stack and pcb.
- * The address space is released by "vmspace_free(p->p_vmspace)";
- * This is machine-dependent, as we may have to change stacks
- * or ensure that the current one isn't reallocated before we
- * finish. cpu_exit will end with a call to cpu_switch(), finishing
- * our execution (pun intended).
+ * The address space is released by "vmspace_free(p->p_vmspace)"
+ * in vm_waitproc();
*/
cpu_exit(p);
+
+ PROC_LOCK(p);
+ mtx_lock_spin(&sched_lock);
+ while (mtx_owned(&Giant))
+ mtx_unlock_flags(&Giant, MTX_NOSWITCH);
+
+ /*
+ * We have to wait until after releasing all locks before
+ * changing p_stat. If we block on a mutex then we will be
+ * back at SRUN when we resume and our parent will never
+ * harvest us.
+ */
+ p->p_stat = SZOMB;
+
+ wakeup(p->p_pptr);
+ PROC_UNLOCK_NOSWITCH(p);
+
+ cnt.v_swtch++;
+ cpu_throw();
+ panic("exit1");
}
#ifdef COMPAT_43
@@ -571,11 +590,11 @@ loop:
}
/*
- * Give machine-dependent layer a chance
+ * Give vm and machine-dependent layer a chance
* to free anything that cpu_exit couldn't
* release while still running in process context.
*/
- cpu_wait(p);
+ vm_waitproc(p);
mtx_destroy(&p->p_mtx);
zfree(proc_zone, p);
nprocs--;
diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c
index dea8ff0..af154c3 100644
--- a/sys/kern/kern_fork.c
+++ b/sys/kern/kern_fork.c
@@ -235,7 +235,7 @@ fork1(p1, flags, procp)
* certain parts of a process from itself.
*/
if ((flags & RFPROC) == 0) {
- vm_fork(p1, 0, flags);
+ vm_forkproc(p1, 0, flags);
/*
* Close all file descriptors.
@@ -412,7 +412,7 @@ again:
/*
* Duplicate sub-structures as needed.
* Increase reference counts on shared objects.
- * The p_stats and p_sigacts substructs are set in vm_fork.
+ * The p_stats and p_sigacts substructs are set in vm_forkproc.
*/
p2->p_flag = 0;
mtx_lock_spin(&sched_lock);
@@ -461,7 +461,7 @@ again:
PROC_LOCK(p1);
bcopy(p1->p_procsig, p2->p_procsig, sizeof(*p2->p_procsig));
p2->p_procsig->ps_refcnt = 1;
- p2->p_sigacts = NULL; /* finished in vm_fork() */
+ p2->p_sigacts = NULL; /* finished in vm_forkproc() */
}
if (flags & RFLINUXTHPN)
p2->p_sigparent = SIGUSR1;
@@ -573,7 +573,7 @@ again:
* Finish creating the child process. It will return via a different
* execution path later. (ie: directly into user mode)
*/
- vm_fork(p1, p2, flags);
+ vm_forkproc(p1, p2, flags);
if (flags == (RFFDG | RFPROC)) {
cnt.v_forks++;
OpenPOWER on IntegriCloud