From owner-svn-src-all@FreeBSD.ORG Sun Nov 25 14:53:27 2012 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 2A21B22F; Sun, 25 Nov 2012 14:53:27 +0000 (UTC) (envelope-from avg@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) by mx1.freebsd.org (Postfix) with ESMTP id 0F4F18FC08; Sun, 25 Nov 2012 14:53:27 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.5/8.14.5) with ESMTP id qAPErQYq078440; Sun, 25 Nov 2012 14:53:26 GMT (envelope-from avg@svn.freebsd.org) Received: (from avg@localhost) by svn.freebsd.org (8.14.5/8.14.5/Submit) id qAPErQ4S078439; Sun, 25 Nov 2012 14:53:26 GMT (envelope-from avg@svn.freebsd.org) Message-Id: <201211251453.qAPErQ4S078439@svn.freebsd.org> From: Andriy Gapon Date: Sun, 25 Nov 2012 14:53:26 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r243517 - head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs X-SVN-Group: head 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.14 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, 25 Nov 2012 14:53:27 -0000 Author: avg Date: Sun Nov 25 14:53:26 2012 New Revision: 243517 URL: http://svnweb.freebsd.org/changeset/base/243517 Log: zfs_getpages: optimize for large block sizes MFC after: 6 weeks 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 Sun Nov 25 14:25:08 2012 (r243516) +++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c Sun Nov 25 14:53:26 2012 (r243517) @@ -5556,34 +5556,61 @@ zfs_getpages(struct vnode *vp, vm_page_t znode_t *zp = VTOZ(vp); zfsvfs_t *zfsvfs = zp->z_zfsvfs; objset_t *os = zp->z_zfsvfs->z_os; - vm_page_t mreq; + vm_page_t mfirst, mlast, mreq; vm_object_t object; caddr_t va; struct sf_buf *sf; + off_t startoff, endoff; int i, error; - int pcount, size; + vm_pindex_t reqstart, reqend; + int pcount, lsize, reqsize, size; ZFS_ENTER(zfsvfs); ZFS_VERIFY_ZP(zp); - pcount = round_page(count) / PAGE_SIZE; + pcount = OFF_TO_IDX(round_page(count)); mreq = m[reqpage]; object = mreq->object; error = 0; KASSERT(vp->v_object == object, ("mismatching object")); + if (pcount > 1 && zp->z_blksz > PAGESIZE) { + startoff = rounddown(IDX_TO_OFF(mreq->pindex), zp->z_blksz); + reqstart = OFF_TO_IDX(round_page(startoff)); + if (reqstart < m[0]->pindex) + reqstart = 0; + else + reqstart = reqstart - m[0]->pindex; + endoff = roundup(IDX_TO_OFF(mreq->pindex) + PAGE_SIZE, + zp->z_blksz); + reqend = OFF_TO_IDX(trunc_page(endoff)) - 1; + if (reqend > m[pcount - 1]->pindex) + reqend = m[pcount - 1]->pindex; + reqsize = reqend - m[reqstart]->pindex + 1; + KASSERT(reqstart <= reqpage && reqpage < reqstart + reqsize, + ("reqpage beyond [reqstart, reqstart + reqsize[ bounds")); + } else { + reqstart = reqpage; + reqsize = 1; + } + mfirst = m[reqstart]; + mlast = m[reqstart + reqsize - 1]; + VM_OBJECT_LOCK(object); - for (i = 0; i < pcount; i++) { - if (i != reqpage) { - vm_page_lock(m[i]); - vm_page_free(m[i]); - vm_page_unlock(m[i]); - } + for (i = 0; i < reqstart; i++) { + vm_page_lock(m[i]); + vm_page_free(m[i]); + vm_page_unlock(m[i]); + } + for (i = reqstart + reqsize; i < pcount; i++) { + vm_page_lock(m[i]); + vm_page_free(m[i]); + vm_page_unlock(m[i]); } - if (mreq->valid) { + if (mreq->valid && reqsize == 1) { if (mreq->valid != VM_PAGE_BITS_ALL) vm_page_zero_invalid(mreq, TRUE); VM_OBJECT_UNLOCK(object); @@ -5592,30 +5619,66 @@ zfs_getpages(struct vnode *vp, vm_page_t } PCPU_INC(cnt.v_vnodein); - PCPU_INC(cnt.v_vnodepgsin); + PCPU_ADD(cnt.v_vnodepgsin, reqsize); if (IDX_TO_OFF(mreq->pindex) >= object->un_pager.vnp.vnp_size) { + for (i = reqstart; i < reqstart + reqsize; i++) { + if (i != reqpage) { + vm_page_lock(m[i]); + vm_page_free(m[i]); + vm_page_unlock(m[i]); + } + } VM_OBJECT_UNLOCK(object); ZFS_EXIT(zfsvfs); return (VM_PAGER_BAD); } - size = PAGE_SIZE; - if (IDX_TO_OFF(mreq->pindex) + size > object->un_pager.vnp.vnp_size) - size = object->un_pager.vnp.vnp_size - IDX_TO_OFF(mreq->pindex); + lsize = PAGE_SIZE; + if (IDX_TO_OFF(mlast->pindex) + lsize > object->un_pager.vnp.vnp_size) + lsize = object->un_pager.vnp.vnp_size - IDX_TO_OFF(mlast->pindex); VM_OBJECT_UNLOCK(object); - va = zfs_map_page(mreq, &sf); - error = dmu_read(os, zp->z_id, IDX_TO_OFF(mreq->pindex), - size, va, DMU_READ_PREFETCH); - if (size != PAGE_SIZE) - bzero(va + size, PAGE_SIZE - size); - zfs_unmap_page(sf); + + for (i = reqstart; i < reqstart + reqsize; i++) { + size = PAGE_SIZE; + if (i == (reqstart + reqsize - 1)) + size = lsize; + va = zfs_map_page(m[i], &sf); + error = dmu_read(os, zp->z_id, IDX_TO_OFF(m[i]->pindex), + size, va, DMU_READ_PREFETCH); + if (size != PAGE_SIZE) + bzero(va + size, PAGE_SIZE - size); + zfs_unmap_page(sf); + if (error != 0) + break; + } + VM_OBJECT_LOCK(object); - if (!error) - mreq->valid = VM_PAGE_BITS_ALL; - KASSERT(mreq->dirty == 0, ("zfs_getpages: page %p is dirty", mreq)); + for (i = reqstart; i < reqstart + reqsize; i++) { + m[i]->valid = VM_PAGE_BITS_ALL; + KASSERT(m[i]->dirty == 0, ("zfs_getpages: page %p is dirty", m[i])); + if (i != reqpage) { + if (!error) { + if (m[i]->oflags & VPO_WANTED) { + vm_page_lock(m[i]); + vm_page_activate(m[i]); + vm_page_unlock(m[i]); + } else { + vm_page_lock(m[i]); + vm_page_deactivate(m[i]); + vm_page_unlock(m[i]); + } + vm_page_wakeup(m[i]); + } else { + vm_page_lock(m[i]); + vm_page_free(m[i]); + vm_page_unlock(m[i]); + } + } + + } VM_OBJECT_UNLOCK(object);