Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 1 Aug 2016 06:35:35 +0000 (UTC)
From:      Konstantin Belousov <kib@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org
Subject:   svn commit: r303607 - stable/10/sys/kern
Message-ID:  <201608010635.u716ZZbI059351@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: kib
Date: Mon Aug  1 06:35:35 2016
New Revision: 303607
URL: https://svnweb.freebsd.org/changeset/base/303607

Log:
  MFC r302614:
  Revive the check, disabled in r197963.
  
  MFC r302999:
  On first exec after vfork(), call signotify() to handle pending
  reenabled signals.

Modified:
  stable/10/sys/kern/kern_exec.c
  stable/10/sys/kern/subr_trap.c
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/sys/kern/kern_exec.c
==============================================================================
--- stable/10/sys/kern/kern_exec.c	Mon Aug  1 06:34:55 2016	(r303606)
+++ stable/10/sys/kern/kern_exec.c	Mon Aug  1 06:35:35 2016	(r303607)
@@ -751,6 +751,8 @@ interpret:
 	if (p->p_flag & P_PPWAIT) {
 		p->p_flag &= ~(P_PPWAIT | P_PPTRACE);
 		cv_broadcast(&p->p_pwait);
+		/* STOPs are no longer ignored, arrange for AST */
+		signotify(td);
 	}
 
 	/*

Modified: stable/10/sys/kern/subr_trap.c
==============================================================================
--- stable/10/sys/kern/subr_trap.c	Mon Aug  1 06:34:55 2016	(r303606)
+++ stable/10/sys/kern/subr_trap.c	Mon Aug  1 06:35:35 2016	(r303607)
@@ -108,17 +108,29 @@ userret(struct thread *td, struct trapfr
             td->td_name);
 	KASSERT((p->p_flag & P_WEXIT) == 0,
 	    ("Exiting process returns to usermode"));
-#if 0
 #ifdef DIAGNOSTIC
-	/* Check that we called signotify() enough. */
-	PROC_LOCK(p);
-	thread_lock(td);
-	if (SIGPENDING(td) && ((td->td_flags & TDF_NEEDSIGCHK) == 0 ||
-	    (td->td_flags & TDF_ASTPENDING) == 0))
-		printf("failed to set signal flags properly for ast()\n");
-	thread_unlock(td);
-	PROC_UNLOCK(p);
-#endif
+	/*
+	 * Check that we called signotify() enough.  For
+	 * multi-threaded processes, where signal distribution might
+	 * change due to other threads changing sigmask, the check is
+	 * racy and cannot be performed reliably.
+	 * If current process is vfork child, indicated by P_PPWAIT, then
+	 * issignal() ignores stops, so we block the check to avoid
+	 * classifying pending signals.
+	 */
+	if (p->p_numthreads == 1) {
+		PROC_LOCK(p);
+		thread_lock(td);
+		if ((p->p_flag & P_PPWAIT) == 0) {
+			KASSERT(!SIGPENDING(td) || (td->td_flags &
+			    (TDF_NEEDSIGCHK | TDF_ASTPENDING)) ==
+			    (TDF_NEEDSIGCHK | TDF_ASTPENDING),
+			    ("failed to set signal flags for ast p %p "
+			    "td %p fl %x", p, td, td->td_flags));
+		}
+		thread_unlock(td);
+		PROC_UNLOCK(p);
+	}
 #endif
 #ifdef KTRACE
 	KTRUSERRET(td);
@@ -268,6 +280,29 @@ ast(struct trapframe *framep)
 #endif
 	}
 
+#ifdef DIAGNOSTIC
+	if (p->p_numthreads == 1 && (flags & TDF_NEEDSIGCHK) == 0) {
+		PROC_LOCK(p);
+		thread_lock(td);
+		/*
+		 * Note that TDF_NEEDSIGCHK should be re-read from
+		 * td_flags, since signal might have been delivered
+		 * after we cleared td_flags above.  This is one of
+		 * the reason for looping check for AST condition.
+		 * See comment in userret() about P_PPWAIT.
+		 */
+		if ((p->p_flag & P_PPWAIT) == 0) {
+			KASSERT(!SIGPENDING(td) || (td->td_flags &
+			    (TDF_NEEDSIGCHK | TDF_ASTPENDING)) ==
+			    (TDF_NEEDSIGCHK | TDF_ASTPENDING),
+			    ("failed2 to set signal flags for ast p %p td %p "
+			    "fl %x %x", p, td, flags, td->td_flags));
+		}
+		thread_unlock(td);
+		PROC_UNLOCK(p);
+	}
+#endif
+
 	/*
 	 * Check for signals. Unlocked reads of p_pendingcnt or
 	 * p_siglist might cause process-directed signal to be handled



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