diff options
author | kib <kib@FreeBSD.org> | 2014-12-08 16:02:02 +0000 |
---|---|---|
committer | kib <kib@FreeBSD.org> | 2014-12-08 16:02:02 +0000 |
commit | efcd39f69106aa75014cbe681deae31729c4c517 (patch) | |
tree | 872f7adaffc75bea46575c9d6e677c67c5063a96 /sys/kern/kern_exit.c | |
parent | 83eecb0f130044eb9d10ddf12d3dcf487d8a51ca (diff) | |
download | FreeBSD-src-efcd39f69106aa75014cbe681deae31729c4c517.zip FreeBSD-src-efcd39f69106aa75014cbe681deae31729c4c517.tar.gz |
When process is exiting, check for suspension regardless of
multithreaded status of the process.
The stopped state must be cleared before P_WEXIT is set. A stop
signal delivered just before first PROC_LOCK() block in exit1(9) would
put the process into pending stop with P_WEXIT set or assertion
triggered. Also recheck for the suspension after failed
thread_single(9) call, since process lock could be dropped.
Reported and tested by: pho
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Diffstat (limited to 'sys/kern/kern_exit.c')
-rw-r--r-- | sys/kern/kern_exit.c | 25 |
1 files changed, 16 insertions, 9 deletions
diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c index 21daee1..224e6db 100644 --- a/sys/kern/kern_exit.c +++ b/sys/kern/kern_exit.c @@ -182,14 +182,15 @@ exit1(struct thread *td, int rv) * MUST abort all other threads before proceeding past here. */ PROC_LOCK(p); + /* + * First check if some other thread or external request got + * here before us. If so, act appropriately: exit or suspend. + * We must ensure that stop requests are handled before we set + * P_WEXIT. + */ + thread_suspend_check(0); while (p->p_flag & P_HADTHREADS) { /* - * First check if some other thread got here before us. - * If so, act appropriately: exit or suspend. - */ - thread_suspend_check(0); - - /* * Kill off the other threads. This requires * some co-operation from other parts of the kernel * so it may not be instantaneous. With this state set @@ -207,12 +208,18 @@ exit1(struct thread *td, int rv) * either be suspended there or exit. */ if (!thread_single(SINGLE_EXIT)) + /* + * All other activity in this process is now + * stopped. Threading support has been turned + * off. + */ break; - /* - * All other activity in this process is now stopped. - * Threading support has been turned off. + * Recheck for new stop or suspend requests which + * might appear while process lock was dropped in + * thread_single(). */ + thread_suspend_check(0); } KASSERT(p->p_numthreads == 1, ("exit1: proc %p exiting with %d threads", p, p->p_numthreads)); |