summaryrefslogtreecommitdiffstats
path: root/sys/kern
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2014-12-15 10:46:07 +0000
committerkib <kib@FreeBSD.org>2014-12-15 10:46:07 +0000
commit014daa8f250fa7181e72f7495dd3602045257539 (patch)
treef4a4457f24af857e818781d409cdfaf6a32fa871 /sys/kern
parentf3b24d37fe0bc2f15b3611d3908de277f59199ae (diff)
downloadFreeBSD-src-014daa8f250fa7181e72f7495dd3602045257539.zip
FreeBSD-src-014daa8f250fa7181e72f7495dd3602045257539.tar.gz
MFC r275616:
Thread waiting for the vfork(2)-ed child to exec or exit, must allow for the suspension. MFC r275683 (by andreast): Fix build for powerpc(32|64) kernels. MFC r275686 (by andreast): Fix kernel build for booke. r275639 (by andrew) is not merged, since arm/arm/syscall.c is not present on the stable/10 branch, and arm/arm/trap.c already includes sys/kernel.h.
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/kern_thread.c16
-rw-r--r--sys/kern/subr_syscall.c15
2 files changed, 27 insertions, 4 deletions
diff --git a/sys/kern/kern_thread.c b/sys/kern/kern_thread.c
index 122a13d..8a49311 100644
--- a/sys/kern/kern_thread.c
+++ b/sys/kern/kern_thread.c
@@ -724,6 +724,19 @@ stopme:
return (0);
}
+bool
+thread_suspend_check_needed(void)
+{
+ struct proc *p;
+ struct thread *td;
+
+ td = curthread;
+ p = td->td_proc;
+ PROC_LOCK_ASSERT(p, MA_OWNED);
+ return (P_SHOULDSTOP(p) || ((p->p_flag & P_TRACED) != 0 &&
+ (td->td_dbgflags & TDB_SUSPEND) != 0));
+}
+
/*
* Called in from locations that can safely check to see
* whether we have to suspend or at least throttle for a
@@ -768,8 +781,7 @@ thread_suspend_check(int return_instead)
p = td->td_proc;
mtx_assert(&Giant, MA_NOTOWNED);
PROC_LOCK_ASSERT(p, MA_OWNED);
- while (P_SHOULDSTOP(p) ||
- ((p->p_flag & P_TRACED) && (td->td_dbgflags & TDB_SUSPEND))) {
+ while (thread_suspend_check_needed()) {
if (P_SHOULDSTOP(p) == P_STOPPED_SINGLE) {
KASSERT(p->p_singlethread != NULL,
("singlethread not set"));
diff --git a/sys/kern/subr_syscall.c b/sys/kern/subr_syscall.c
index 3d6dc5a..32872bc 100644
--- a/sys/kern/subr_syscall.c
+++ b/sys/kern/subr_syscall.c
@@ -227,9 +227,20 @@ syscallret(struct thread *td, int error, struct syscall_args *sa __unused)
*/
td->td_pflags &= ~TDP_RFPPWAIT;
p2 = td->td_rfppwait_p;
+again:
PROC_LOCK(p2);
- while (p2->p_flag & P_PPWAIT)
- cv_wait(&p2->p_pwait, &p2->p_mtx);
+ while (p2->p_flag & P_PPWAIT) {
+ PROC_LOCK(p);
+ if (thread_suspend_check_needed()) {
+ PROC_UNLOCK(p2);
+ thread_suspend_check(0);
+ PROC_UNLOCK(p);
+ goto again;
+ } else {
+ PROC_UNLOCK(p);
+ }
+ cv_timedwait(&p2->p_pwait, &p2->p_mtx, hz);
+ }
PROC_UNLOCK(p2);
}
}
OpenPOWER on IntegriCloud