From: Matthew Dillon Date: Mon, 18 Jan 2010 01:53:47 +0000 (-0800) Subject: kernel - Finish implementing PG_RAM / pipelined mmap operation X-Git-Tag: v2.7.1~229^2~86 X-Git-Url: https://gitweb.dragonflybsd.org/dragonfly.git/commitdiff_plain/1c48c95257b6b028b6cd5f31af60e0d545e951bc kernel - Finish implementing PG_RAM / pipelined mmap operation * Finish implementing the PG_RAM read-ahead mark code. This code allows the VM system to generate pipelining faults when reading a memory mapped file sequentially. This allows programs which scan files via mmap() to max-out the I/O system, similar to read(). Before this change programs using mmap() could not get better then ~70-80% disk utilization for sequential I/O. This commit passes the sequential access flag through to the VOP_GETPAGES code which then adjusts the sequential access heuristic in the ioflags accordingly. --- diff --git a/sys/kern/vfs_default.c b/sys/kern/vfs_default.c index ad986f8921..7dd0df69f8 100644 --- a/sys/kern/vfs_default.c +++ b/sys/kern/vfs_default.c @@ -1258,7 +1258,7 @@ vop_stdgetpages(struct vop_getpages_args *ap) if ((mp = ap->a_vp->v_mount) != NULL) { error = vnode_pager_generic_getpages( ap->a_vp, ap->a_m, ap->a_count, - ap->a_reqpage); + ap->a_reqpage, ap->a_seqaccess); } else { error = VM_PAGER_BAD; } diff --git a/sys/kern/vfs_vopops.c b/sys/kern/vfs_vopops.c index ae116c4ee1..de8130d717 100644 --- a/sys/kern/vfs_vopops.c +++ b/sys/kern/vfs_vopops.c @@ -946,7 +946,7 @@ vop_reallocblks(struct vop_ops *ops, struct vnode *vp, */ int vop_getpages(struct vop_ops *ops, struct vnode *vp, vm_page_t *m, int count, - int reqpage, vm_ooffset_t offset) + int reqpage, vm_ooffset_t offset, int seqaccess) { struct vop_getpages_args ap; VFS_MPLOCK_DECLARE; @@ -959,6 +959,7 @@ vop_getpages(struct vop_ops *ops, struct vnode *vp, vm_page_t *m, int count, ap.a_count = count; ap.a_reqpage = reqpage; ap.a_offset = offset; + ap.a_seqaccess = seqaccess; VFS_MPLOCK1(vp->v_mount); DO_OPS(ops, error, &ap, vop_getpages); diff --git a/sys/sys/vfsops.h b/sys/sys/vfsops.h index fdb6c6c9b1..64105c19a9 100644 --- a/sys/sys/vfsops.h +++ b/sys/sys/vfsops.h @@ -347,6 +347,7 @@ struct vop_getpages_args { int a_count; int a_reqpage; vm_ooffset_t a_offset; + int a_seqaccess; }; struct vop_putpages_args { @@ -794,7 +795,7 @@ int vop_balloc(struct vop_ops *ops, struct vnode *vp, off_t startoffset, int vop_reallocblks(struct vop_ops *ops, struct vnode *vp, struct cluster_save *buflist); int vop_getpages(struct vop_ops *ops, struct vnode *vp, struct vm_page **m, - int count, int reqpage, vm_ooffset_t offset); + int count, int reqpage, vm_ooffset_t offset, int seqaccess); int vop_putpages(struct vop_ops *ops, struct vnode *vp, struct vm_page **m, int count, int sync, int *rtvals, vm_ooffset_t offset); int vop_freeblks(struct vop_ops *ops, struct vnode *vp, @@ -1023,8 +1024,8 @@ extern struct syslink_desc vop_nrename_desc; vop_balloc(*(vp)->v_ops, vp, offset, size, cred, flags, bpp) #define VOP_REALLOCBLKS(vp, buflist) \ vop_reallocblks(*(vp)->v_ops, vp, buflist) -#define VOP_GETPAGES(vp, m, count, reqpage, off) \ - vop_getpages(*(vp)->v_ops, vp, m, count, reqpage, off) +#define VOP_GETPAGES(vp, m, count, reqpage, off, seqaccess) \ + vop_getpages(*(vp)->v_ops, vp, m, count, reqpage, off, seqaccess) #define VOP_PUTPAGES(vp, m, count, sync, rtvals, off) \ vop_putpages(*(vp)->v_ops, vp, m, count, sync, rtvals, off) #define VOP_FREEBLKS(vp, offset, length) \ diff --git a/sys/vfs/gnu/ext2fs/ext2_vnops.c b/sys/vfs/gnu/ext2fs/ext2_vnops.c index 99b0bb5488..e38235eefe 100644 --- a/sys/vfs/gnu/ext2fs/ext2_vnops.c +++ b/sys/vfs/gnu/ext2fs/ext2_vnops.c @@ -1242,8 +1242,11 @@ bad: static int ext2_getpages(struct vop_getpages_args *ap) { - return (vnode_pager_generic_getpages(ap->a_vp, ap->a_m, ap->a_count, - ap->a_reqpage)); + int error; + + error = vnode_pager_generic_getpages(ap->a_vp, ap->a_m, ap->a_count, + ap->a_reqpage, ap->a_seqaccess); + return(error); } void diff --git a/sys/vfs/nwfs/nwfs_io.c b/sys/vfs/nwfs/nwfs_io.c index d153baa0d6..78888ad799 100644 --- a/sys/vfs/nwfs/nwfs_io.c +++ b/sys/vfs/nwfs/nwfs_io.c @@ -377,7 +377,7 @@ nwfs_getpages(struct vop_getpages_args *ap) { #ifndef NWFS_RWCACHE return vnode_pager_generic_getpages(ap->a_vp, ap->a_m, ap->a_count, - ap->a_reqpage); + ap->a_reqpage, ap->a_seqaccess); #else int i, error, npages; size_t nextoff, toff; diff --git a/sys/vfs/ufs/ufs_readwrite.c b/sys/vfs/ufs/ufs_readwrite.c index 33038e9633..d5d55f6039 100644 --- a/sys/vfs/ufs/ufs_readwrite.c +++ b/sys/vfs/ufs/ufs_readwrite.c @@ -478,8 +478,8 @@ ffs_getpages(struct vop_getpages_args *ap) if (bsize < PAGE_SIZE) return vnode_pager_generic_getpages(ap->a_vp, ap->a_m, - ap->a_count, - ap->a_reqpage); + ap->a_count, ap->a_reqpage, + ap->a_seqaccess); /* * foff is the file offset of the required page @@ -566,7 +566,8 @@ ffs_getpages(struct vop_getpages_args *ap) physoffset -= foff; dp = VTOI(ap->a_vp)->i_devvp; rtval = VOP_GETPAGES(dp, &ap->a_m[firstpage], size, - (ap->a_reqpage - firstpage), physoffset); + (ap->a_reqpage - firstpage), physoffset, + ap->a_seqaccess); return (rtval); } diff --git a/sys/vfs/union/union_vnops.c b/sys/vfs/union/union_vnops.c index 203e4dbe84..ef36d616ce 100644 --- a/sys/vfs/union/union_vnops.c +++ b/sys/vfs/union/union_vnops.c @@ -1000,8 +1000,9 @@ union_getpages(struct vop_getpages_args *ap) { int r; - r = vnode_pager_generic_getpages(ap->a_vp, ap->a_m, - ap->a_count, ap->a_reqpage); + r = vnode_pager_generic_getpages(ap->a_vp, ap->a_m, + ap->a_count, ap->a_reqpage, + ap->a_seqaccess); return(r); } diff --git a/sys/vm/vnode_pager.c b/sys/vm/vnode_pager.c index 62b91cb046..0d32dd9c42 100644 --- a/sys/vm/vnode_pager.c +++ b/sys/vm/vnode_pager.c @@ -392,7 +392,7 @@ vnode_pager_getpage(vm_object_t object, vm_page_t *mpp, int seqaccess) struct vnode *vp; vp = object->handle; - rtval = VOP_GETPAGES(vp, mpp, PAGE_SIZE, 0, 0); + rtval = VOP_GETPAGES(vp, mpp, PAGE_SIZE, 0, 0, seqaccess); if (rtval == EOPNOTSUPP) panic("vnode_pager: vfs's must implement vop_getpages\n"); return rtval; @@ -409,7 +409,7 @@ vnode_pager_getpage(vm_object_t object, vm_page_t *mpp, int seqaccess) */ int vnode_pager_generic_getpages(struct vnode *vp, vm_page_t *mpp, int bytecount, - int reqpage) + int reqpage, int seqaccess) { struct iovec aiov; struct uio auio; @@ -498,7 +498,7 @@ vnode_pager_generic_getpages(struct vnode *vp, vm_page_t *mpp, int bytecount, * Issue the I/O with some read-ahead if bytecount > PAGE_SIZE */ ioflags = IO_VMIO; -/* if (bytecount > PAGE_SIZE)*/ + if (seqaccess) ioflags |= IO_SEQMAX << IO_SEQSHIFT; aiov.iov_base = NULL; diff --git a/sys/vm/vnode_pager.h b/sys/vm/vnode_pager.h index 969924448f..0a9997bae7 100644 --- a/sys/vm/vnode_pager.h +++ b/sys/vm/vnode_pager.h @@ -60,7 +60,7 @@ struct vnode *vnode_pager_lock (vm_object_t); * XXX Generic routines; currently called by badly written FS code; these * XXX should go away soon. */ -int vnode_pager_generic_getpages (struct vnode *, vm_page_t *, int, int); +int vnode_pager_generic_getpages (struct vnode *, vm_page_t *, int, int, int); int vnode_pager_generic_putpages (struct vnode *, vm_page_t *, int, boolean_t, int *); #endif