summaryrefslogtreecommitdiffstats
path: root/sys/kern
diff options
context:
space:
mode:
authordavidxu <davidxu@FreeBSD.org>2008-10-24 01:03:31 +0000
committerdavidxu <davidxu@FreeBSD.org>2008-10-24 01:03:31 +0000
commite66e7ee6bbe3a5b6d25e28eba2984a209a1d69da (patch)
tree155e2292d15151c02e028236ab56960d1587f709 /sys/kern
parent2e4682de7537d80bbc49cc4b8072dd2d237e2a9d (diff)
downloadFreeBSD-src-e66e7ee6bbe3a5b6d25e28eba2984a209a1d69da.zip
FreeBSD-src-e66e7ee6bbe3a5b6d25e28eba2984a209a1d69da.tar.gz
partly revert revision 184199, because TDF_NEEDSIGCHK is persitent
when thread is in kernel mode, it can cause dead loop, now unlock process lock after acquired sleep queue lock and thread lock to avoid the problem. This means TDF_NEEDSIGCHK and TDF_NEEDSUSPCHK must be set with process lock and thread lock being hold at same time.
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/subr_sleepqueue.c15
1 files changed, 5 insertions, 10 deletions
diff --git a/sys/kern/subr_sleepqueue.c b/sys/kern/subr_sleepqueue.c
index 751fa64..0f00a70 100644
--- a/sys/kern/subr_sleepqueue.c
+++ b/sys/kern/subr_sleepqueue.c
@@ -396,7 +396,6 @@ sleepq_catch_signals(void *wchan, int pri)
return (0);
}
-catch_sig:
thread_unlock(td);
mtx_unlock_spin(&sc->sc_lock);
CTR3(KTR_PROC, "sleepq catching signals: thread %p (pid %ld, %s)",
@@ -416,19 +415,15 @@ catch_sig:
ret = ERESTART;
mtx_unlock(&ps->ps_mtx);
}
- PROC_UNLOCK(p);
mtx_lock_spin(&sc->sc_lock);
thread_lock(td);
- if (ret != 0)
- goto out;
- if ((td->td_flags & (TDF_NEEDSIGCHK | TDF_NEEDSUSPCHK)) != 0)
- goto catch_sig;
-
- sleepq_switch(wchan, pri);
- return (0);
+ PROC_UNLOCK(p);
+ if (ret == 0) {
+ sleepq_switch(wchan, pri);
+ return (0);
+ }
-out:
/*
* There were pending signals and this thread is still
* on the sleep queue, remove it from the sleep queue.
OpenPOWER on IntegriCloud