Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 8 Dec 2014 16:02:02 +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: r275615 - head/sys/kern
Message-ID:  <201412081602.sB8G22F4085965@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: kib
Date: Mon Dec  8 16:02:02 2014
New Revision: 275615
URL: https://svnweb.freebsd.org/changeset/base/275615

Log:
  When process is exiting, check for suspension regardless of
  multithreaded status of the process.
  
  The stopped state must be cleared before P_WEXIT is set.  A stop
  signal delivered just before first PROC_LOCK() block in exit1(9) would
  put the process into pending stop with P_WEXIT set or assertion
  triggered.  Also recheck for the suspension after failed
  thread_single(9) call, since process lock could be dropped.
  
  Reported and tested by:	pho
  Sponsored by:	The FreeBSD Foundation
  MFC after:	1 week

Modified:
  head/sys/kern/kern_exit.c

Modified: head/sys/kern/kern_exit.c
==============================================================================
--- head/sys/kern/kern_exit.c	Mon Dec  8 15:47:52 2014	(r275614)
+++ head/sys/kern/kern_exit.c	Mon Dec  8 16:02:02 2014	(r275615)
@@ -182,14 +182,15 @@ exit1(struct thread *td, int rv)
 	 * MUST abort all other threads before proceeding past here.
 	 */
 	PROC_LOCK(p);
+	/*
+	 * First check if some other thread or external request got
+	 * here before us.  If so, act appropriately: exit or suspend.
+	 * We must ensure that stop requests are handled before we set
+	 * P_WEXIT.
+	 */
+	thread_suspend_check(0);
 	while (p->p_flag & P_HADTHREADS) {
 		/*
-		 * First check if some other thread got here before us.
-		 * If so, act appropriately: exit or suspend.
-		 */
-		thread_suspend_check(0);
-
-		/*
 		 * Kill off the other threads. This requires
 		 * some co-operation from other parts of the kernel
 		 * so it may not be instantaneous.  With this state set
@@ -207,12 +208,18 @@ exit1(struct thread *td, int rv)
 		 * either be suspended there or exit.
 		 */
 		if (!thread_single(SINGLE_EXIT))
+			/*
+			 * All other activity in this process is now
+			 * stopped.  Threading support has been turned
+			 * off.
+			 */
 			break;
-
 		/*
-		 * All other activity in this process is now stopped.
-		 * Threading support has been turned off.
+		 * Recheck for new stop or suspend requests which
+		 * might appear while process lock was dropped in
+		 * thread_single().
 		 */
+		thread_suspend_check(0);
 	}
 	KASSERT(p->p_numthreads == 1,
 	    ("exit1: proc %p exiting with %d threads", p, p->p_numthreads));



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