diff options
author | kib <kib@FreeBSD.org> | 2014-12-15 10:46:07 +0000 |
---|---|---|
committer | kib <kib@FreeBSD.org> | 2014-12-15 10:46:07 +0000 |
commit | 014daa8f250fa7181e72f7495dd3602045257539 (patch) | |
tree | f4a4457f24af857e818781d409cdfaf6a32fa871 /sys | |
parent | f3b24d37fe0bc2f15b3611d3908de277f59199ae (diff) | |
download | FreeBSD-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')
-rw-r--r-- | sys/kern/kern_thread.c | 16 | ||||
-rw-r--r-- | sys/kern/subr_syscall.c | 15 | ||||
-rw-r--r-- | sys/powerpc/aim/trap.c | 1 | ||||
-rw-r--r-- | sys/powerpc/booke/trap.c | 1 | ||||
-rw-r--r-- | sys/sys/proc.h | 1 |
5 files changed, 30 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); } } diff --git a/sys/powerpc/aim/trap.c b/sys/powerpc/aim/trap.c index 9b9801f..c2db1cf 100644 --- a/sys/powerpc/aim/trap.c +++ b/sys/powerpc/aim/trap.c @@ -48,6 +48,7 @@ __FBSDID("$FreeBSD$"); #include <sys/syscall.h> #include <sys/sysent.h> #include <sys/systm.h> +#include <sys/kernel.h> #include <sys/uio.h> #include <sys/signalvar.h> #include <sys/vmmeter.h> diff --git a/sys/powerpc/booke/trap.c b/sys/powerpc/booke/trap.c index 476f77f..eacd3e7 100644 --- a/sys/powerpc/booke/trap.c +++ b/sys/powerpc/booke/trap.c @@ -48,6 +48,7 @@ __FBSDID("$FreeBSD$"); #include <sys/syscall.h> #include <sys/sysent.h> #include <sys/systm.h> +#include <sys/kernel.h> #include <sys/uio.h> #include <sys/signalvar.h> #include <sys/vmmeter.h> diff --git a/sys/sys/proc.h b/sys/sys/proc.h index 6865fe9..891d296 100644 --- a/sys/sys/proc.h +++ b/sys/sys/proc.h @@ -947,6 +947,7 @@ void childproc_stopped(struct proc *child, int reason); void childproc_continued(struct proc *child); void childproc_exited(struct proc *child); int thread_suspend_check(int how); +bool thread_suspend_check_needed(void); void thread_suspend_switch(struct thread *); void thread_suspend_one(struct thread *td); void thread_unlink(struct thread *td); |