kernel - Finish implementing PG_RAM / pipelined mmap operation
authorMatthew Dillon <dillon@apollo.backplane.com>
Mon, 18 Jan 2010 01:53:47 +0000 (17:53 -0800)
committerMatthew Dillon <dillon@apollo.backplane.com>
Mon, 18 Jan 2010 01:53:47 +0000 (17:53 -0800)
* 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.

sys/kern/vfs_default.c
sys/kern/vfs_vopops.c
sys/sys/vfsops.h
sys/vfs/gnu/ext2fs/ext2_vnops.c
sys/vfs/nwfs/nwfs_io.c
sys/vfs/ufs/ufs_readwrite.c
sys/vfs/union/union_vnops.c
sys/vm/vnode_pager.c
sys/vm/vnode_pager.h

index ad986f8..7dd0df6 100644 (file)
@@ -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;
        }
index ae116c4..de8130d 100644 (file)
@@ -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);
index fdb6c6c..64105c1 100644 (file)
@@ -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)               \
index 99b0bb5..e38235e 100644 (file)
@@ -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
index d153baa..78888ad 100644 (file)
@@ -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;
index 33038e9..d5d55f6 100644 (file)
@@ -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);
 }
index 203e4db..ef36d61 100644 (file)
@@ -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);
 }
 
index 62b91cb..0d32dd9 100644 (file)
@@ -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;
index 9699244..0a9997b 100644 (file)
@@ -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