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>