From owner-svn-src-all@freebsd.org Fri Nov 10 12:45:10 2017 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id D760DE6D29D; Fri, 10 Nov 2017 12:45:10 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id A40D371F40; Fri, 10 Nov 2017 12:45:10 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id vAACj9UZ083895; Fri, 10 Nov 2017 12:45:09 GMT (envelope-from kib@FreeBSD.org) Received: (from kib@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id vAACj9Ls083894; Fri, 10 Nov 2017 12:45:09 GMT (envelope-from kib@FreeBSD.org) Message-Id: <201711101245.vAACj9Ls083894@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: kib set sender to kib@FreeBSD.org using -f From: Konstantin Belousov Date: Fri, 10 Nov 2017 12:45:09 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org Subject: svn commit: r325645 - stable/11/sys/vm X-SVN-Group: stable-11 X-SVN-Commit-Author: kib X-SVN-Commit-Paths: stable/11/sys/vm X-SVN-Commit-Revision: 325645 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 10 Nov 2017 12:45:11 -0000 Author: kib Date: Fri Nov 10 12:45:09 2017 New Revision: 325645 URL: https://svnweb.freebsd.org/changeset/base/325645 Log: MFC r324807: Take the vm object lock in read mode in vnode_generic_putpages(). Modified: stable/11/sys/vm/vnode_pager.c Directory Properties: stable/11/ (props changed) Modified: stable/11/sys/vm/vnode_pager.c ============================================================================== --- stable/11/sys/vm/vnode_pager.c Fri Nov 10 12:42:50 2017 (r325644) +++ stable/11/sys/vm/vnode_pager.c Fri Nov 10 12:45:09 2017 (r325645) @@ -1211,8 +1211,14 @@ vnode_pager_generic_putpages(struct vnode *vp, vm_page * We do not under any circumstances truncate the valid bits, as * this will screw up bogus page replacement. */ - VM_OBJECT_WLOCK(object); + VM_OBJECT_RLOCK(object); if (maxsize + poffset > object->un_pager.vnp.vnp_size) { + if (!VM_OBJECT_TRYUPGRADE(object)) { + VM_OBJECT_RUNLOCK(object); + VM_OBJECT_WLOCK(object); + if (maxsize + poffset <= object->un_pager.vnp.vnp_size) + goto downgrade; + } if (object->un_pager.vnp.vnp_size > poffset) { maxsize = object->un_pager.vnp.vnp_size - poffset; ncount = btoc(maxsize); @@ -1237,6 +1243,8 @@ vnode_pager_generic_putpages(struct vnode *vp, vm_page } for (i = ncount; i < count; i++) rtvals[i] = VM_PAGER_BAD; +downgrade: + VM_OBJECT_LOCK_DOWNGRADE(object); } auio.uio_iov = &aiov; @@ -1283,7 +1291,7 @@ start_write: */ MPASS(prev_offset < next_offset); - VM_OBJECT_WUNLOCK(object); + VM_OBJECT_RUNLOCK(object); aiov.iov_base = NULL; auio.uio_iovcnt = 1; auio.uio_offset = prev_offset; @@ -1299,7 +1307,7 @@ start_write: "zero-length write at %ju resid %zd\n", auio.uio_offset, auio.uio_resid); } - VM_OBJECT_WLOCK(object); + VM_OBJECT_RLOCK(object); break; } @@ -1317,7 +1325,7 @@ start_write: vn_printf(vp, "vnode_pager_putpages: residual I/O %zd " "at %ju\n", auio.uio_resid, (uintmax_t)ma[0]->pindex); - VM_OBJECT_WLOCK(object); + VM_OBJECT_RLOCK(object); if (error != 0 || auio.uio_resid != 0) break; } @@ -1331,7 +1339,7 @@ write_done: /* Unwritten pages in range, free bonus if the page is clean. */ for (; i < ncount; i++) rtvals[i] = ma[i]->dirty == 0 ? VM_PAGER_OK : VM_PAGER_ERROR; - VM_OBJECT_WUNLOCK(object); + VM_OBJECT_RUNLOCK(object); PCPU_ADD(cnt.v_vnodepgsout, i); PCPU_INC(cnt.v_vnodeout); return (rtvals[0]);