Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 27 Feb 2012 21:10:11 +0000 (UTC)
From:      Konstantin Belousov <kib@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r232240 - in head/sys: kern sys
Message-ID:  <201202272110.q1RLABjb037139@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: kib
Date: Mon Feb 27 21:10:10 2012
New Revision: 232240
URL: http://svn.freebsd.org/changeset/base/232240

Log:
  Currently, the debugger attached to the process executing vfork() does
  not get syscall exit notification until the child performed exec of
  exit.  Swap the order of doing ptracestop() and waiting for P_PPWAIT
  clearing, by postponing the wait into syscallret after ptracestop()
  notification is done.
  
  Reported, tested and reviewed by:	Dmitry Mikulin <dmitrym juniper net>
  MFC after:	 2 weeks

Modified:
  head/sys/kern/kern_fork.c
  head/sys/kern/subr_syscall.c
  head/sys/sys/proc.h

Modified: head/sys/kern/kern_fork.c
==============================================================================
--- head/sys/kern/kern_fork.c	Mon Feb 27 20:52:20 2012	(r232239)
+++ head/sys/kern/kern_fork.c	Mon Feb 27 21:10:10 2012	(r232240)
@@ -708,6 +708,10 @@ do_fork(struct thread *td, int flags, st
 		_PHOLD(p2);
 		p2_held = 1;
 	}
+	if (flags & RFPPWAIT) {
+		td->td_pflags |= TDP_RFPPWAIT;
+		td->td_rfppwait_p = p2;
+	}
 	PROC_UNLOCK(p2);
 	if ((flags & RFSTOPPED) == 0) {
 		/*
@@ -740,14 +744,6 @@ do_fork(struct thread *td, int flags, st
 		cv_wait(&p2->p_dbgwait, &p2->p_mtx);
 	if (p2_held)
 		_PRELE(p2);
-
-	/*
-	 * Preserve synchronization semantics of vfork.  If waiting for
-	 * child to exec or exit, set P_PPWAIT on child, and sleep on our
-	 * proc (in case of exit).
-	 */
-	while (p2->p_flag & P_PPWAIT)
-		cv_wait(&p2->p_pwait, &p2->p_mtx);
 	PROC_UNLOCK(p2);
 }
 

Modified: head/sys/kern/subr_syscall.c
==============================================================================
--- head/sys/kern/subr_syscall.c	Mon Feb 27 20:52:20 2012	(r232239)
+++ head/sys/kern/subr_syscall.c	Mon Feb 27 21:10:10 2012	(r232240)
@@ -165,7 +165,7 @@ syscallenter(struct thread *td, struct s
 static inline void
 syscallret(struct thread *td, int error, struct syscall_args *sa __unused)
 {
-	struct proc *p;
+	struct proc *p, *p2;
 	int traced;
 
 	p = td->td_proc;
@@ -223,4 +223,23 @@ syscallret(struct thread *td, int error,
 		td->td_dbgflags &= ~(TDB_SCX | TDB_EXEC | TDB_FORK);
 		PROC_UNLOCK(p);
 	}
+
+	if (td->td_pflags & TDP_RFPPWAIT) {
+		/*
+		 * Preserve synchronization semantics of vfork.  If
+		 * waiting for child to exec or exit, fork set
+		 * P_PPWAIT on child, and there we sleep on our proc
+		 * (in case of exit).
+		 *
+		 * Do it after the ptracestop() above is finished, to
+		 * not block our debugger until child execs or exits
+		 * to finish vfork wait.
+		 */
+		td->td_pflags &= ~TDP_RFPPWAIT;
+		p2 = td->td_rfppwait_p;
+		PROC_LOCK(p2);
+		while (p2->p_flag & P_PPWAIT)
+			cv_wait(&p2->p_pwait, &p2->p_mtx);
+		PROC_UNLOCK(p2);
+	}
 }

Modified: head/sys/sys/proc.h
==============================================================================
--- head/sys/sys/proc.h	Mon Feb 27 20:52:20 2012	(r232239)
+++ head/sys/sys/proc.h	Mon Feb 27 21:10:10 2012	(r232240)
@@ -311,6 +311,7 @@ struct thread {
 	struct vnet	*td_vnet;	/* (k) Effective vnet. */
 	const char	*td_vnet_lpush;	/* (k) Debugging vnet push / pop. */
 	struct trapframe *td_intr_frame;/* (k) Frame of the current irq */
+	struct proc *td_rfppwait_p;	/* (k) The vforked child */
 };
 
 struct mtx *thread_lock_block(struct thread *);
@@ -415,6 +416,7 @@ do {									\
 #define	TDP_CALLCHAIN	0x00400000 /* Capture thread's callchain */
 #define	TDP_IGNSUSP	0x00800000 /* Permission to ignore the MNTK_SUSPEND* */
 #define	TDP_AUDITREC	0x01000000 /* Audit record pending on thread */
+#define	TDP_RFPPWAIT	0x02000000 /* Handle RFPPWAIT on syscall exit */
 
 /*
  * Reasons that the current thread can not be run yet.



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201202272110.q1RLABjb037139>