When creation of the v_pollinfo raced and our instance of vpollinfo

must be destroyed, knlist_clear() and seldrain() calls could be
avoided, since vpollinfo was not used.  More, the knlist_clear()
calling protocol requires the knlist locked, which is not true at the
call site.

Split the destruction into the helper destroy_vpollinfo_free(), and
call it when raced, instead of destroy_vpollinfo().

Reported and tested by:	pho
Sponsored by:	The FreeBSD Foundation
MFC after:   3 days
This commit is contained in:
Konstantin Belousov 2013-07-28 06:59:29 +00:00
parent b5a4266b48
commit 2c38cc792e

View File

@ -3452,15 +3452,22 @@ vfs_msync(struct mount *mp, int flags)
}
}
static void
destroy_vpollinfo_free(struct vpollinfo *vi)
{
knlist_destroy(&vi->vpi_selinfo.si_note);
mtx_destroy(&vi->vpi_lock);
uma_zfree(vnodepoll_zone, vi);
}
static void
destroy_vpollinfo(struct vpollinfo *vi)
{
knlist_clear(&vi->vpi_selinfo.si_note, 1);
seldrain(&vi->vpi_selinfo);
knlist_destroy(&vi->vpi_selinfo.si_note);
mtx_destroy(&vi->vpi_lock);
uma_zfree(vnodepoll_zone, vi);
destroy_vpollinfo_free(vi);
}
/*
@ -3480,7 +3487,7 @@ v_addpollinfo(struct vnode *vp)
VI_LOCK(vp);
if (vp->v_pollinfo != NULL) {
VI_UNLOCK(vp);
destroy_vpollinfo(vi);
destroy_vpollinfo_free(vi);
return;
}
vp->v_pollinfo = vi;