From owner-svn-src-all@FreeBSD.ORG Sun May 24 17:16:56 2015 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 1C6E6BE6; Sun, 24 May 2015 17:16:56 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::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 098E71A67; Sun, 24 May 2015 17:16:56 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.9/8.14.9) with ESMTP id t4OHGtsn013719; Sun, 24 May 2015 17:16:55 GMT (envelope-from mav@FreeBSD.org) Received: (from mav@localhost) by svn.freebsd.org (8.14.9/8.14.9/Submit) id t4OHGtCh013718; Sun, 24 May 2015 17:16:55 GMT (envelope-from mav@FreeBSD.org) Message-Id: <201505241716.t4OHGtCh013718@svn.freebsd.org> X-Authentication-Warning: svn.freebsd.org: mav set sender to mav@FreeBSD.org using -f From: Alexander Motin Date: Sun, 24 May 2015 17:16:55 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org Subject: svn commit: r283458 - stable/9/sys/fs/nfsclient X-SVN-Group: stable-9 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.20 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: Sun, 24 May 2015 17:16:56 -0000 Author: mav Date: Sun May 24 17:16:55 2015 New Revision: 283458 URL: https://svnweb.freebsd.org/changeset/base/283458 Log: MFC r282881: Do not promote large async writes to sync. Present implementation of large sync writes is too strict and so can be quite slow. Instead of doing that, execute large async write in chunks, syncing each chunk separately. It would be good to fix large sync writes too, but I leave it to somebody with more skills in this area. Modified: stable/9/sys/fs/nfsclient/nfs_clbio.c Directory Properties: stable/9/ (props changed) stable/9/sys/ (props changed) stable/9/sys/fs/ (props changed) Modified: stable/9/sys/fs/nfsclient/nfs_clbio.c ============================================================================== --- stable/9/sys/fs/nfsclient/nfs_clbio.c Sun May 24 17:16:30 2015 (r283457) +++ stable/9/sys/fs/nfsclient/nfs_clbio.c Sun May 24 17:16:55 2015 (r283458) @@ -874,7 +874,7 @@ ncl_write(struct vop_write_args *ap) struct nfsmount *nmp = VFSTONFS(vp->v_mount); daddr_t lbn; int bcount, noncontig_write, obcount; - int bp_cached, n, on, error = 0, error1; + int bp_cached, n, on, error = 0, error1, wouldcommit; size_t orig_resid, local_resid; off_t orig_size, tmp_off; @@ -918,7 +918,6 @@ ncl_write(struct vop_write_args *ap) if (ioflag & IO_NDELAY) return (EAGAIN); #endif -flush_and_restart: np->n_attrstamp = 0; KDTRACE_NFS_ATTRCACHE_FLUSH_DONE(vp); error = ncl_vinvalbuf(vp, V_SAVE, td, 1); @@ -975,27 +974,14 @@ flush_and_restart: * IO_UNIT -- we just make all writes atomic anyway, as there's * no point optimizing for something that really won't ever happen. */ + wouldcommit = 0; if (!(ioflag & IO_SYNC)) { int nflag; mtx_lock(&np->n_mtx); nflag = np->n_flag; mtx_unlock(&np->n_mtx); - int needrestart = 0; - if (nmp->nm_wcommitsize < uio->uio_resid) { - /* - * If this request could not possibly be completed - * without exceeding the maximum outstanding write - * commit size, see if we can convert it into a - * synchronous write operation. - */ - if (ioflag & IO_NDELAY) - return (EAGAIN); - ioflag |= IO_SYNC; - if (nflag & NMODIFIED) - needrestart = 1; - } else if (nflag & NMODIFIED) { - int wouldcommit = 0; + if (nflag & NMODIFIED) { BO_LOCK(&vp->v_bufobj); if (vp->v_bufobj.bo_dirty.bv_cnt != 0) { TAILQ_FOREACH(bp, &vp->v_bufobj.bo_dirty.bv_hd, @@ -1005,27 +991,22 @@ flush_and_restart: } } BO_UNLOCK(&vp->v_bufobj); - /* - * Since we're not operating synchronously and - * bypassing the buffer cache, we are in a commit - * and holding all of these buffers whether - * transmitted or not. If not limited, this - * will lead to the buffer cache deadlocking, - * as no one else can flush our uncommitted buffers. - */ - wouldcommit += uio->uio_resid; - /* - * If we would initially exceed the maximum - * outstanding write commit size, flush and restart. - */ - if (wouldcommit > nmp->nm_wcommitsize) - needrestart = 1; } - if (needrestart) - goto flush_and_restart; } do { + if (!(ioflag & IO_SYNC)) { + wouldcommit += biosize; + if (wouldcommit > nmp->nm_wcommitsize) { + np->n_attrstamp = 0; + KDTRACE_NFS_ATTRCACHE_FLUSH_DONE(vp); + error = ncl_vinvalbuf(vp, V_SAVE, td, 1); + if (error) + return (error); + wouldcommit = biosize; + } + } + NFSINCRGLOBAL(newnfsstats.biocache_writes); lbn = uio->uio_offset / biosize; on = uio->uio_offset & (biosize-1);