summaryrefslogtreecommitdiffstats
path: root/sys/kern/subr_sleepqueue.c
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/subr_sleepqueue.c
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/subr_sleepqueue.c')
-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