Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 2 Nov 2012 01:32:22 +0000 (UTC)
From:      Jamie Gritton <jamie@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org
Subject:   svn commit: r242464 - stable/8/sys/kern
Message-ID:  <201211020132.qA21WMnd016831@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: jamie
Date: Fri Nov  2 01:32:22 2012
New Revision: 242464
URL: http://svn.freebsd.org/changeset/base/242464

Log:
  MFC r225191:
  
   Delay the recursive decrement of pr_uref when jails are made invisible
   but not removed; decrement it instead when the child jail actually
   goes away. This avoids letting the counter go below zero in the case
   where dying (pr_uref==0) jails are "resurrected", and an associated
   KASSERT panic.
  
  PR:		kern/173120
  Submitted by:	Steven Hartland

Modified:
  stable/8/sys/kern/kern_jail.c
Directory Properties:
  stable/8/sys/   (props changed)
  stable/8/sys/kern/   (props changed)

Modified: stable/8/sys/kern/kern_jail.c
==============================================================================
--- stable/8/sys/kern/kern_jail.c	Fri Nov  2 01:20:55 2012	(r242463)
+++ stable/8/sys/kern/kern_jail.c	Fri Nov  2 01:32:22 2012	(r242464)
@@ -2454,32 +2454,11 @@ prison_deref(struct prison *pr, int flag
 
 	if (!(flags & PD_LOCKED))
 		mtx_lock(&pr->pr_mtx);
-	/* Decrement the user references in a separate loop. */
-	if (flags & PD_DEUREF) {
-		for (tpr = pr;; tpr = tpr->pr_parent) {
-			if (tpr != pr)
-				mtx_lock(&tpr->pr_mtx);
-			if (--tpr->pr_uref > 0)
-				break;
-			KASSERT(tpr != &prison0, ("prison0 pr_uref=0"));
-			mtx_unlock(&tpr->pr_mtx);
-		}
-		/* Done if there were only user references to remove. */
-		if (!(flags & PD_DEREF)) {
-			mtx_unlock(&tpr->pr_mtx);
-			if (flags & PD_LIST_SLOCKED)
-				sx_sunlock(&allprison_lock);
-			else if (flags & PD_LIST_XLOCKED)
-				sx_xunlock(&allprison_lock);
-			return;
-		}
-		if (tpr != pr) {
-			mtx_unlock(&tpr->pr_mtx);
-			mtx_lock(&pr->pr_mtx);
-		}
-	}
-
 	for (;;) {
+		if (flags & PD_DEUREF) {
+			pr->pr_uref--;
+			KASSERT(prison0.pr_uref != 0, ("prison0 pr_uref=0"));
+		}
 		if (flags & PD_DEREF)
 			pr->pr_ref--;
 		/* If the prison still has references, nothing else to do. */
@@ -2532,7 +2511,7 @@ prison_deref(struct prison *pr, int flag
 		/* Removing a prison frees a reference on its parent. */
 		pr = ppr;
 		mtx_lock(&pr->pr_mtx);
-		flags = PD_DEREF;
+		flags = PD_DEREF | PD_DEUREF;
 	}
 }
 



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