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:
parent
b5a4266b48
commit
2c38cc792e
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user