summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_exit.c
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2014-12-08 16:02:02 +0000
committerkib <kib@FreeBSD.org>2014-12-08 16:02:02 +0000
commitefcd39f69106aa75014cbe681deae31729c4c517 (patch)
tree872f7adaffc75bea46575c9d6e677c67c5063a96 /sys/kern/kern_exit.c
parent83eecb0f130044eb9d10ddf12d3dcf487d8a51ca (diff)
downloadFreeBSD-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.c25
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));
OpenPOWER on IntegriCloud