Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 28 Jul 2013 06:59:29 +0000 (UTC)
From:      Konstantin Belousov <kib@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r253737 - head/sys/kern
Message-ID:  <201307280659.r6S6xT6G041740@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: kib
Date: Sun Jul 28 06:59:29 2013
New Revision: 253737
URL: http://svnweb.freebsd.org/changeset/base/253737

Log:
  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

Modified:
  head/sys/kern/vfs_subr.c

Modified: head/sys/kern/vfs_subr.c
==============================================================================
--- head/sys/kern/vfs_subr.c	Sun Jul 28 06:16:12 2013	(r253736)
+++ head/sys/kern/vfs_subr.c	Sun Jul 28 06:59:29 2013	(r253737)
@@ -3453,16 +3453,23 @@ vfs_msync(struct mount *mp, int flags)
 }
 
 static void
-destroy_vpollinfo(struct vpollinfo *vi)
+destroy_vpollinfo_free(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);
 }
 
+static void
+destroy_vpollinfo(struct vpollinfo *vi)
+{
+
+	knlist_clear(&vi->vpi_selinfo.si_note, 1);
+	seldrain(&vi->vpi_selinfo);
+	destroy_vpollinfo_free(vi);
+}
+
 /*
  * Initalize per-vnode helper structure to hold poll-related state.
  */
@@ -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;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201307280659.r6S6xT6G041740>