From 2c38cc792e3df242c9de071640934bf8ab5e8ad7 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Sun, 28 Jul 2013 06:59:29 +0000 Subject: [PATCH] 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 --- sys/kern/vfs_subr.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c index e2c28130d59b..6fb49ae7dbe4 100644 --- a/sys/kern/vfs_subr.c +++ b/sys/kern/vfs_subr.c @@ -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;