Move cpu_exit() earlier in exit1() to close a race between
SIGCHLD/kevent(2) notification of process termination and wait(). Now we no longer drop locks between sending the notification and marking the process as a zombie. Previously, if another process attempted to do a wait() with W_NOHANG after receiving a SIGCHLD or kevent and locked the process while the exiting thread was in cpu_exit(), then wait() would fail to find the process, which is quite astonishing to the process calling wait(). MFC after: 3 days
This commit is contained in:
parent
2b1170b7f0
commit
77d161b46b
@ -405,6 +405,16 @@ exit1(struct thread *td, int rv)
|
||||
LIST_REMOVE(p, p_hash);
|
||||
sx_xunlock(&allproc_lock);
|
||||
|
||||
/*
|
||||
* Call machine-dependent code to release any
|
||||
* machine-dependent resources other than the address space.
|
||||
* The address space is released by "vmspace_exitfree(p)" in
|
||||
* vm_waitproc().
|
||||
*/
|
||||
cpu_exit(td);
|
||||
|
||||
WITNESS_WARN(WARN_PANIC, NULL, "process (pid %d) exiting", p->p_pid);
|
||||
|
||||
/*
|
||||
* Reparent all of our children to init.
|
||||
*/
|
||||
@ -484,22 +494,6 @@ exit1(struct thread *td, int rv)
|
||||
else /* LINUX thread */
|
||||
psignal(p->p_pptr, p->p_sigparent);
|
||||
}
|
||||
PROC_UNLOCK(p->p_pptr);
|
||||
PROC_UNLOCK(p);
|
||||
|
||||
/*
|
||||
* Finally, call machine-dependent code to release the remaining
|
||||
* resources including address space.
|
||||
* The address space is released by "vmspace_exitfree(p)" in
|
||||
* vm_waitproc().
|
||||
*/
|
||||
cpu_exit(td);
|
||||
|
||||
WITNESS_WARN(WARN_PANIC, &proctree_lock.lock_object,
|
||||
"process (pid %d) exiting", p->p_pid);
|
||||
|
||||
PROC_LOCK(p);
|
||||
PROC_LOCK(p->p_pptr);
|
||||
sx_xunlock(&proctree_lock);
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user