summaryrefslogtreecommitdiffstats
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
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.
-rw-r--r--sys/kern/kern_thread.c16
-rw-r--r--sys/kern/subr_syscall.c15
-rw-r--r--sys/powerpc/aim/trap.c1
-rw-r--r--sys/powerpc/booke/trap.c1
-rw-r--r--sys/sys/proc.h1
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);
OpenPOWER on IntegriCloud