From owner-svn-src-all@FreeBSD.ORG Tue Nov 16 15:53:44 2010 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id CAE6D1065670; Tue, 16 Nov 2010 15:53:44 +0000 (UTC) (envelope-from avg@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 9F0778FC0C; Tue, 16 Nov 2010 15:53:44 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id oAGFriYr059426; Tue, 16 Nov 2010 15:53:44 GMT (envelope-from avg@svn.freebsd.org) Received: (from avg@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id oAGFri1a059424; Tue, 16 Nov 2010 15:53:44 GMT (envelope-from avg@svn.freebsd.org) Message-Id: <201011161553.oAGFri1a059424@svn.freebsd.org> From: Andriy Gapon Date: Tue, 16 Nov 2010 15:53:44 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r215401 - head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 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: Tue, 16 Nov 2010 15:53:44 -0000 Author: avg Date: Tue Nov 16 15:53:44 2010 New Revision: 215401 URL: http://svn.freebsd.org/changeset/base/215401 Log: zfs+sendfile: populate all requested pages, not just those already cached kern_sendfile() uses vm_rdwr() to read-ahead blocks of data to populate page cache. When sendfile stumbles upon a page that is not populated yet, it sends out all the mbufs that it collected so far. This resulted in very poor performance with ZFS when file data is not in the page cache, because ZFS vop_read for UIO_NOCOPY case populated only those pages that are already in cache, but not valid. Which means that most of the time it populated only the first requested page in the described above scenario. Reported by: Alexander Zagrebin Tested by: Alexander Zagrebin , Artemiev Igor MFC after: 12 days Modified: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c Modified: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c ============================================================================== --- head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c Tue Nov 16 15:02:53 2010 (r215400) +++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c Tue Nov 16 15:53:44 2010 (r215401) @@ -67,6 +67,7 @@ #include #include #include +#include /* * Programming rules. @@ -481,7 +482,7 @@ again: uiomove_fromphys(&m, off, bytes, uio); VM_OBJECT_LOCK(obj); vm_page_wakeup(m); - } else if (m != NULL && uio->uio_segflg == UIO_NOCOPY) { + } else if (uio->uio_segflg == UIO_NOCOPY) { /* * The code below is here to make sendfile(2) work * correctly with ZFS. As pointed out by ups@ @@ -491,7 +492,7 @@ again: */ KASSERT(off == 0, ("unexpected offset in mappedread for sendfile")); - if ((m->oflags & VPO_BUSY) != 0) { + if (m != NULL && (m->oflags & VPO_BUSY) != 0) { /* * Reference the page before unlocking and * sleeping so that the page daemon is less @@ -501,8 +502,17 @@ again: vm_page_flag_set(m, PG_REFERENCED); vm_page_sleep(m, "zfsmrb"); goto again; + } else if (m == NULL) { + m = vm_page_alloc(obj, OFF_TO_IDX(start), + VM_ALLOC_NOBUSY | VM_ALLOC_NORMAL); + if (m == NULL) { + VM_OBJECT_UNLOCK(obj); + VM_WAIT; + VM_OBJECT_LOCK(obj); + goto again; + } } - vm_page_busy(m); + vm_page_io_start(m); VM_OBJECT_UNLOCK(obj); if (dirbytes > 0) { error = dmu_read_uio(os, zp->z_id, uio, @@ -520,7 +530,7 @@ again: VM_OBJECT_LOCK(obj); if (error == 0) m->valid = VM_PAGE_BITS_ALL; - vm_page_wakeup(m); + vm_page_io_finish(m); if (error == 0) { uio->uio_resid -= bytes; uio->uio_offset += bytes;