From owner-p4-projects@FreeBSD.ORG Mon Feb 27 19:43:39 2012 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id F40FB1065675; Mon, 27 Feb 2012 19:43:38 +0000 (UTC) Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id B6CB0106566B for ; Mon, 27 Feb 2012 19:43:38 +0000 (UTC) (envelope-from jhb@freebsd.org) Received: from skunkworks.freebsd.org (skunkworks.freebsd.org [IPv6:2001:4f8:fff6::2d]) by mx1.freebsd.org (Postfix) with ESMTP id A45D38FC12 for ; Mon, 27 Feb 2012 19:43:38 +0000 (UTC) Received: from skunkworks.freebsd.org (localhost [127.0.0.1]) by skunkworks.freebsd.org (8.14.4/8.14.4) with ESMTP id q1RJhcdZ074211 for ; Mon, 27 Feb 2012 19:43:38 GMT (envelope-from jhb@freebsd.org) Received: (from perforce@localhost) by skunkworks.freebsd.org (8.14.4/8.14.4/Submit) id q1RJhcs9074208 for perforce@freebsd.org; Mon, 27 Feb 2012 19:43:38 GMT (envelope-from jhb@freebsd.org) Date: Mon, 27 Feb 2012 19:43:38 GMT Message-Id: <201202271943.q1RJhcs9074208@skunkworks.freebsd.org> X-Authentication-Warning: skunkworks.freebsd.org: perforce set sender to jhb@freebsd.org using -f From: John Baldwin To: Perforce Change Reviews Precedence: bulk Cc: Subject: PERFORCE change 206993 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 27 Feb 2012 19:43:39 -0000 http://p4web.freebsd.org/@@206993?ac=10 Change 206993 by jhb@jhb_jhbbsd on 2012/02/27 19:43:20 Attempt to optimize for the common case of using NOREUSE with sequential access by tracking NOREUSE reads and if they are sequential, applying DONTNEED to the entire range that has been read so far. Also, make UFS restrict DONTNEED requests to block boundaries to avoid flushing partial blocks from RAM. Affected files ... .. //depot/projects/fadvise/sys/kern/vfs_syscalls.c#19 edit .. //depot/projects/fadvise/sys/kern/vfs_vnops.c#7 edit .. //depot/projects/fadvise/sys/sys/file.h#8 edit .. //depot/projects/fadvise/sys/ufs/ffs/ffs_vnops.c#4 edit Differences ... ==== //depot/projects/fadvise/sys/kern/vfs_syscalls.c#19 (text+ko) ==== @@ -4950,6 +4950,8 @@ new->fa_advice = advice; new->fa_start = offset; new->fa_end = end; + new->fa_prevstart = 0; + new->fa_prevend = 0; fp->f_advice = new; new = fa; } ==== //depot/projects/fadvise/sys/kern/vfs_vnops.c#7 (text+ko) ==== @@ -519,7 +519,7 @@ int error, ioflag; struct mtx *mtxp; int advice, vfslocked; - off_t offset; + off_t offset, start, end; KASSERT(uio->uio_td == td, ("uio_td %p is not td %p", uio->uio_td, td)); @@ -584,9 +584,38 @@ fp->f_nextoff = uio->uio_offset; VOP_UNLOCK(vp, 0); if (error == 0 && advice == POSIX_FADV_NOREUSE && - offset != uio->uio_offset) - error = VOP_ADVISE(vp, offset, uio->uio_offset - 1, - POSIX_FADV_DONTNEED); + offset != uio->uio_offset) { + /* + * Use POSIX_FADV_DONTNEED to flush clean pages and + * buffers for the backing file after a + * POSIX_FADV_NOREUSE read(2). To optimize the common + * case of using POSIX_FADV_NOREUSE with sequential + * access, track the previous implicit DONTNEED + * request and grow this request to include the + * current read(2) in addition to the previous + * DONTNEED. Withpurely sequential access this will + * cause the DONTNEED requests to continously grow to + * cover all of the previously read regions of the + * file. This allows filesystem blocks that are + * accessed by multiple calls to read(2) to be flushed + * once the last read(2) finishes. + */ + start = offset; + end = uio->uio_offset - 1; + mtx_lock(mtxp); + if (fp->f_advice != NULL && + fp->f_advice->fa_advice == POSIX_FADV_NOREUSE) { + if (start != 0 && fp->f_advice->fa_prevend + 1 == start) + start = fp->f_advice->fa_prevstart; + else if (fp->f_advice->fa_prevstart != 0 && + fp->f_advice->fa_prevstart == end + 1) + end = fp->f_advice->fa_prevend; + fp->f_advice->fa_prevstart = start; + fp->f_advice->fa_prevend = end; + } + mtx_unlock(mtxp); + error = VOP_ADVISE(vp, start, end, POSIX_FADV_DONTNEED); + } VFS_UNLOCK_GIANT(vfslocked); return (error); } ==== //depot/projects/fadvise/sys/sys/file.h#8 (text+ko) ==== @@ -126,6 +126,8 @@ int fa_advice; /* (f) FADV_* type. */ off_t fa_start; /* (f) Region start. */ off_t fa_end; /* (f) Region end. */ + off_t fa_prevstart; /* (f) Previous NOREUSE start. */ + off_t fa_prevend; /* (f) Previous NOREUSE end. */ }; struct file { ==== //depot/projects/fadvise/sys/ufs/ffs/ffs_vnops.c#4 (text+ko) ==== @@ -422,6 +422,43 @@ int xfersize; switch (ap->a_advice) { + case POSIX_FADV_DONTNEED: + /* + * Trim requests to only cover full blocks to avoid + * flushing partial blocks. + */ + vp = ap->a_vp; + start = ap->a_start; + end = ap->a_end; + vn_lock(vp, LK_SHARED | LK_RETRY); + if (vp->v_iflag & VI_DOOMED) { + VOP_UNLOCK(vp, 0); + return (EBADF); + } + KASSERT(vp->v_type == VREG, ("FADV_DONTNEED on bad vnode")); + ip = VTOI(vp); + if (start >= ip->i_size) { + VOP_UNLOCK(vp, 0); + return (0); + } + fs = ip->i_fs; + if (blkoffset(fs, start) != 0) { + size = blksize(fs, ip, lblkno(fs, start)); + start += size - blkoffset(fs, start); + KASSERT(blkoffset(fs, start) == 0, + ("failed to adjust range start to block boundary")); + } + if (end < ip->i_size && blkoffset(fs, end) != 0) { + end -= blkoffset(fs, end); + KASSERT(blkoffset(fs, end) == 0, + ("failed to adjust range end to block boundary")); + } + VOP_UNLOCK(vp, 0); + if (start > end) + return (0); + ap->a_start = start; + ap->a_end = end; + return (vop_stdadvise(ap)); case POSIX_FADV_WILLNEED: vp = ap->a_vp; start = ap->a_start;