summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_exit.c
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2004-02-27 18:39:09 +0000
committerjhb <jhb@FreeBSD.org>2004-02-27 18:39:09 +0000
commitd76d63171193672c7e6a895b24e49e7276837c3b (patch)
tree4640f9a2b80424922f4669215053fe8e7a708461 /sys/kern/kern_exit.c
parentd07a9130c61961c9c61c5204f35f878403bfe123 (diff)
downloadFreeBSD-src-d76d63171193672c7e6a895b24e49e7276837c3b.zip
FreeBSD-src-d76d63171193672c7e6a895b24e49e7276837c3b.tar.gz
Drop sched_lock around the wakeup of the parent process after setting
the process state to zombie when a process exits to avoid a lock order reversal with the sleepqueue locks. This appears to be the only place that we call wakeup() with sched_lock held.
Diffstat (limited to 'sys/kern/kern_exit.c')
-rw-r--r--sys/kern/kern_exit.c13
1 files changed, 9 insertions, 4 deletions
diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c
index 84c0680..f81de28 100644
--- a/sys/kern/kern_exit.c
+++ b/sys/kern/kern_exit.c
@@ -494,21 +494,26 @@ exit1(struct thread *td, int rv)
PROC_LOCK(p);
PROC_LOCK(p->p_pptr);
sx_xunlock(&proctree_lock);
- mtx_lock_spin(&sched_lock);
while (mtx_owned(&Giant))
mtx_unlock(&Giant);
/*
* We have to wait until after acquiring all locks before
- * changing p_state. If we block on a mutex then we will be
- * back at SRUN when we resume and our parent will never
- * harvest us.
+ * changing p_state. We need to avoid any possibly context
+ * switches while marked as a zombie including blocking on
+ * a mutex.
*/
+ mtx_lock_spin(&sched_lock);
p->p_state = PRS_ZOMBIE;
+ critical_enter();
+ mtx_unlock_spin(&sched_lock);
wakeup(p->p_pptr);
PROC_UNLOCK(p->p_pptr);
+
+ mtx_lock_spin(&sched_lock);
+ critical_exit();
cnt.v_swtch++;
binuptime(PCPU_PTR(switchtime));
PCPU_SET(switchticks, ticks);
OpenPOWER on IntegriCloud