Date: Fri, 26 Aug 2011 16:03:34 +0000 (UTC) From: Jamie Gritton <jamie@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r225191 - head/sys/kern Message-ID: <201108261603.p7QG3YbF061534@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: jamie Date: Fri Aug 26 16:03:34 2011 New Revision: 225191 URL: http://svn.freebsd.org/changeset/base/225191 Log: 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. Submitted by: Steven Hartland Approved by: re (bz) MFC after: 1 week Modified: head/sys/kern/kern_jail.c Modified: head/sys/kern/kern_jail.c ============================================================================== --- head/sys/kern/kern_jail.c Fri Aug 26 15:24:54 2011 (r225190) +++ head/sys/kern/kern_jail.c Fri Aug 26 16:03:34 2011 (r225191) @@ -2470,32 +2470,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. */ @@ -2551,7 +2530,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?201108261603.p7QG3YbF061534>