Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 4 May 2002 03:59:41 -0700 (PDT)
From:      Jonathan Mini <mini@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 10778 for review
Message-ID:  <200205041059.g44Axfc02100@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://people.freebsd.org/~peter/p4db/chv.cgi?CH=10778

Change 10778 by mini@mini_stylus on 2002/05/04 03:59:35

	- Obtain PROC_LOCK when funneling through thread_single() and
	  thread_single_end().
	- For now, we know that thread_alloc() always succeeds, so don't
	  check for failure and abort (the abort code was incorrect anyways).
	- Add jhb's race comment, although its not entirely accurate.

Affected files ...

... //depot/projects/kse/sys/kern/kern_fork.c#65 edit

Differences ...

==== //depot/projects/kse/sys/kern/kern_fork.c#65 (text+ko) ====

@@ -289,10 +289,13 @@
 		 * be aborted in the child.
 		 * (it is possible we could restart them there as well!)
 		 */ 
+		PROC_LOCK(p1);
 		if (thread_single(SNGLE_WAIT)) {
 			/* abort.. someone else is single threading before us */
+			PROC_UNLOCK(p1);
 			return (ERESTART);
 		}
+		PROC_UNLOCK(p1);
 		/*
 		 * All other activity in this process
 		 * is now suspended at the user boundary,
@@ -315,9 +318,12 @@
 	if ((nprocs >= maxproc - 10 && uid != 0) || nprocs >= maxproc) {
 		sx_xunlock(&allproc_lock);
 		uma_zfree(proc_zone, newproc);
+		if (p1->p_flag & P_KSES) {
+			PROC_LOCK(p1);
+			thread_single_end();
+			PROC_UNLOCK(p1);
+		}
 		tsleep(&forksleep, PUSER, "fork", hz / 2);
-		if (p1->p_flag & P_KSES)
-			thread_single_end();
 		return (EAGAIN);
 	}
 	/*
@@ -332,8 +338,11 @@
 		sx_xunlock(&allproc_lock);
 		uma_zfree(proc_zone, newproc);
 		tsleep(&forksleep, PUSER, "fork", hz / 2);
-		if (p1->p_flag & P_KSES)
+		if (p1->p_flag & P_KSES) {
+			PROC_LOCK(p1);
 			thread_single_end();
+			PROC_UNLOCK(p1);
+		}
 		return (EAGAIN);
 	}
 
@@ -459,14 +468,6 @@
 	 * then copy the section that is copied directly from the parent.
 	 */
 	td2 = thread_alloc();
-	if (td2 == NULL) {
-		/* XXX need to take out of pid hash I think */
-		uma_zfree(proc_zone, p2);
-		nprocs--;
-		if (p1->p_flag & P_KSES)
-			thread_single_end();
-		return (EAGAIN);
-	}
 	ke2 = &p2->p_kse;
 	kg2 = &p2->p_ksegrp;
 
@@ -670,6 +671,19 @@
 	PROC_UNLOCK(p2);
 	sx_xunlock(&proctree_lock);
 
+	/*
+	 * XXXKSE: In KSE, there would be a race here if one thread was
+	 * dieing due to a signal (or calling exit1() for that matter) while
+	 * another thread was calling fork1().  Not sure how KSE wants to work
+	 * around that.  The problem is that up until the point above, if p1
+	 * gets killed, it won't find p2 in its list in order for it to be
+	 * reparented.  Alternatively, we could add a new p_flag that gets set
+	 * before we reparent all the children that we check above and just
+	 * use init as our parent if that if that flag is set.  (Either that
+	 * or abort the fork if the flag is set since our parent died trying
+	 * to fork us (which is evil)).
+	 */
+
 	KASSERT(newprocsig == NULL, ("unused newprocsig"));
 	if (newsigacts != NULL)
 		FREE(newsigacts, M_SUBPROC);

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe p4-projects" in the body of the message




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