Date: Sun, 1 Sep 2002 18:32:14 +1000 (EST) From: Bruce Evans <bde@zeta.org.au> To: Don Lewis <dl-freebsd@catspoiler.org> Cc: kris@obsecurity.org, <current@FreeBSD.ORG>, <phk@FreeBSD.ORG> Subject: Re: Page faults from bento cluster (Re: Problems reading vmcores) Message-ID: <20020901181130.D8550-100000@gamplex.bde.org> In-Reply-To: <200209010726.g817QEwr067908@gw.catspoiler.org>
next in thread | previous in thread | raw e-mail | index | archive | help
On Sun, 1 Sep 2002, Don Lewis wrote: > This code in vflush() bothers me: > > mtx_lock(&mntvnode_mtx); > loop: > for (vp = TAILQ_FIRST(&mp->mnt_nvnodelist); vp; vp = nvp) { > /* > * Make sure this vnode wasn't reclaimed in getnewvnode(). > * Start over if it has (it won't be on the list anymore). > */ > if (vp->v_mount != mp) > goto loop; > nvp = TAILQ_NEXT(vp, v_nmntvnodes); > > mtx_unlock(&mntvnode_mtx); > vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); > /* > * Skip over a vnodes marked VV_SYSTEM. > */ > if ((flags & SKIPSYSTEM) && (vp->v_vflag & VV_SYSTEM)) { > VOP_UNLOCK(vp, 0, td); > mtx_lock(&mntvnode_mtx); > continue; > } > /* > * If WRITECLOSE is set, flush out unlinked but still open > * files (even if open only for reading) and regular file > * vnodes open for writing. > */ > error = VOP_GETATTR(vp, &vattr, td->td_ucred, td); > VI_LOCK(vp); > > As near as I can tell the panic is happening in VOP_GETATTR(). It looks > to me like it would be possible for the vnode to be recycled between the > time when it passes the vp->v_mount test at the top of the loop and the > time when vn_lock() succeeds. Shouldn't we bump the vnode reference > count by calling vref() at the top of the loop and add the appropriate > calls to vrele()? Rev.1.395 made some changes that I didn't like much here. The VOP_GETATTR() is now done unconditionally. This pessimizes vflush() and enlarges any race windows. I think WRITECLOSE is only used for mount -u from rw to ro, so the pessimization exercises code that was rarely used before. Rev.1.394 called VOP_GETATTR() with the interlock held. This was wrong but probably reduced race windows. The window seems to have been opened before rev.1.394 by releasing mntvnode_slock before aquiring the interlock. RELENG_4 doesn't release mntvnode_slock at that point (it holds both locks across the VOP_GETATTR()). Bruce To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-current" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20020901181130.D8550-100000>