Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/yamt-pagecache]: src/sys don't inline uvn_findpages in genfs_io.



details:   https://anonhg.NetBSD.org/src/rev/2e2ba3fff55a
branches:  yamt-pagecache
changeset: 770847:2e2ba3fff55a
user:      yamt <yamt%NetBSD.org@localhost>
date:      Tue Dec 20 13:46:17 2011 +0000

description:
don't inline uvn_findpages in genfs_io.

diffstat:

 sys/miscfs/genfs/genfs_io.c |  94 +++++++++++++++-----------------------------
 sys/uvm/uvm_extern.h        |   8 ++-
 sys/uvm/uvm_vnode.c         |  45 +++++++++++++++-----
 3 files changed, 71 insertions(+), 76 deletions(-)

diffs (truncated from 318 to 300 lines):

diff -r cd2eba7a420f -r 2e2ba3fff55a sys/miscfs/genfs/genfs_io.c
--- a/sys/miscfs/genfs/genfs_io.c       Fri Dec 02 16:54:32 2011 +0000
+++ b/sys/miscfs/genfs/genfs_io.c       Tue Dec 20 13:46:17 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: genfs_io.c,v 1.53.2.5 2011/11/30 14:31:29 yamt Exp $   */
+/*     $NetBSD: genfs_io.c,v 1.53.2.6 2011/12/20 13:46:17 yamt Exp $   */
 
 /*
  * Copyright (c) 1982, 1986, 1989, 1993
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: genfs_io.c,v 1.53.2.5 2011/11/30 14:31:29 yamt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: genfs_io.c,v 1.53.2.6 2011/12/20 13:46:17 yamt Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -217,7 +217,8 @@
                }
 #endif /* defined(DEBUG) */
                nfound = uvn_findpages(uobj, origoffset, &npages,
-                   ap->a_m, UFP_NOWAIT|UFP_NOALLOC|(memwrite ? UFP_NORDONLY : 0));
+                   ap->a_m, NULL,
+                   UFP_NOWAIT|UFP_NOALLOC|(memwrite ? UFP_NORDONLY : 0));
                KASSERT(npages == *ap->a_count);
                if (nfound == 0) {
                        error = EBUSY;
@@ -343,7 +344,7 @@
                goto startover;
        }
 
-       if (uvn_findpages(uobj, origoffset, &npages, &pgs[ridx],
+       if (uvn_findpages(uobj, origoffset, &npages, &pgs[ridx], NULL,
            async ? UFP_NOWAIT : UFP_ALL) != orignmempages) {
                if (!glocked) {
                        genfs_node_unlock(vp);
@@ -430,7 +431,7 @@
                UVMHIST_LOG(ubchist, "reset npages start 0x%x end 0x%x",
                    startoffset, endoffset, 0,0);
                npgs = npages;
-               if (uvn_findpages(uobj, startoffset, &npgs, pgs,
+               if (uvn_findpages(uobj, startoffset, &npgs, pgs, NULL,
                    async ? UFP_NOWAIT : UFP_ALL) != npages) {
                        if (!glocked) {
                                genfs_node_unlock(vp);
@@ -856,7 +857,8 @@
        off_t off;
        /* Even for strange MAXPHYS, the shift rounds down to a page */
 #define maxpages (MAXPHYS >> PAGE_SHIFT)
-       int i, error, npages, nback;
+       int i, error;
+       unsigned int npages, nback;
        int freeflag;
        struct vm_page *pgs[maxpages], *pg;
        struct uvm_page_array a;
@@ -1088,6 +1090,9 @@
                 */
 
                if (needs_clean) {
+                       unsigned int nforw;
+                       unsigned int fpflags;
+
                        KDASSERT((vp->v_iflag & VI_ONWORKLST));
                        wasclean = false;
                        memset(pgs, 0, sizeof(pgs));
@@ -1095,17 +1100,25 @@
                        UVM_PAGE_OWN(pg, "genfs_putpages");
 
                        /*
-                        * first look backward.
-                        *
-                        * XXX implement PG_PAGER1 incompatibility check.
+                        * XXX PG_PAGER1 incompatibility check.
+                        * this is a kludge for nfs.
                         * probably it's better to make PG_NEEDCOMMIT a first
                         * level citizen for uvm/genfs.
                         */
+                       fpflags = UFP_NOWAIT|UFP_NOALLOC|UFP_DIRTYONLY;
+                       if ((pg->flags & PG_PAGER1) != 0) {
+                               fpflags |= UFP_ONLYPAGER1;
+                       } else {
+                               fpflags |= UFP_NOPAGER1;
+                       }
 
+                       /*
+                        * first look backward.
+                        */
                        npages = MIN(maxpages >> 1, off >> PAGE_SHIFT);
                        nback = npages;
                        uvn_findpages(uobj, off - PAGE_SIZE, &nback, &pgs[0],
-                           UFP_NOWAIT|UFP_NOALLOC|UFP_DIRTYONLY|UFP_BACKWARD);
+                           NULL, fpflags | UFP_BACKWARD);
                        if (nback) {
                                memmove(&pgs[0], &pgs[npages - nback],
                                    nback * sizeof(pgs[0]));
@@ -1126,58 +1139,15 @@
                        /*
                         * then look forward to fill in the remaining space in
                         * the array of pages.
+                        *
+                        * pass our cached array of pages so that hopefully
+                        * uvn_findpages can find some good pages in it.
                         */
 
-                       for (npages = 1; npages < maxpages; npages++) {
-                               struct vm_page *nextpg;
-
-                               /*
-                                * regardless of the value of dirtyonly,
-                                * we don't need to care about clean pages here
-                                * as we will drop the object lock to call
-                                * GOP_WRITE and thus need to clear the array
-                                * before the next iteration anyway.
-                                */
-
-                               nextpg = uvm_page_array_fill_and_peek(&a, uobj,
-                                   pgs[npages - 1]->offset + PAGE_SIZE,
-                                   maxpages - npages,
-                                   UVM_PAGE_ARRAY_FILL_DIRTYONLY |
-                                   UVM_PAGE_ARRAY_FILL_DENSE);
-                               if (nextpg == NULL) {
-                                       break;
-                               }
-                               KASSERT(nextpg->uobject == pg->uobject);
-                               KASSERT(nextpg->offset > pg->offset);
-                               KASSERT(nextpg->offset >
-                                   pgs[npages - 1]->offset);
-                               if (pgs[npages - 1]->offset + PAGE_SIZE !=
-                                   nextpg->offset) {
-                                       break;
-                               }
-                               if ((nextpg->flags & PG_BUSY) != 0) {
-                                       break;
-                               }
-
-                               /*
-                                * don't bother to cluster incompatible pages
-                                * together.
-                                *
-                                * XXX hack for nfs
-                                */
-
-                               if (((nextpg->flags ^ pgs[npages - 1]->flags) &
-                                   PG_PAGER1) != 0) {
-                                       break;
-                               }
-                               if (!uvm_pagecheckdirty(nextpg, false)) {
-                                       break;
-                               }
-                               nextpg->flags |= PG_BUSY;
-                               UVM_PAGE_OWN(nextpg, "genfs_putpages2");
-                               pgs[npages] = nextpg;
-                               uvm_page_array_advance(&a);
-                       }
+                       nforw = maxpages - nback - 1;
+                       uvn_findpages(uobj, pg->offset + PAGE_SIZE,
+                           &nforw, &pgs[nback + 1], &a, fpflags);
+                       npages = nback + 1 + nforw;
                } else {
                        pgs[0] = pg;
                        npages = 1;
@@ -1550,7 +1520,7 @@
        pgs = ap->a_m;
 
        if (ap->a_flags & PGO_LOCKED) {
-               uvn_findpages(uobj, origoffset, ap->a_count, ap->a_m,
+               uvn_findpages(uobj, origoffset, ap->a_count, ap->a_m, NULL,
                    UFP_NOWAIT|UFP_NOALLOC| (memwrite ? UFP_NORDONLY : 0));
 
                error = ap->a_m[ap->a_centeridx] == NULL ? EBUSY : 0;
@@ -1568,7 +1538,7 @@
                return 0;
        }
        npages = orignpages;
-       uvn_findpages(uobj, origoffset, &npages, pgs, UFP_ALL);
+       uvn_findpages(uobj, origoffset, &npages, pgs, NULL, UFP_ALL);
        mutex_exit(uobj->vmobjlock);
        kva = uvm_pagermapin(pgs, npages,
            UVMPAGER_MAPIN_READ | UVMPAGER_MAPIN_WAITOK);
diff -r cd2eba7a420f -r 2e2ba3fff55a sys/uvm/uvm_extern.h
--- a/sys/uvm/uvm_extern.h      Fri Dec 02 16:54:32 2011 +0000
+++ b/sys/uvm/uvm_extern.h      Tue Dec 20 13:46:17 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: uvm_extern.h,v 1.176.2.4 2011/11/20 10:52:33 yamt Exp $        */
+/*     $NetBSD: uvm_extern.h,v 1.176.2.5 2011/12/20 13:46:17 yamt Exp $        */
 
 /*
  * Copyright (c) 1997 Charles D. Cranor and Washington University.
@@ -210,6 +210,8 @@
 #define UFP_NORDONLY   0x08
 #define UFP_DIRTYONLY  0x10
 #define UFP_BACKWARD   0x20
+#define UFP_ONLYPAGER1 0x40
+#define UFP_NOPAGER1   0x80
 
 /*
  * lockflags that control the locking behavior of various functions.
@@ -775,10 +777,12 @@
 void                   uvm_deallocate(struct vm_map *, vaddr_t, vsize_t);
 
 /* uvm_vnode.c */
+struct uvm_page_array;
 void                   uvm_vnp_setsize(struct vnode *, voff_t);
 void                   uvm_vnp_setwritesize(struct vnode *, voff_t);
 int                    uvn_findpages(struct uvm_object *, voff_t,
-                           int *, struct vm_page **, int);
+                           unsigned int *, struct vm_page **,
+                           struct uvm_page_array *, unsigned int);
 bool                   uvn_text_p(struct uvm_object *);
 bool                   uvn_clean_p(struct uvm_object *);
 bool                   uvn_needs_writefault_p(struct uvm_object *);
diff -r cd2eba7a420f -r 2e2ba3fff55a sys/uvm/uvm_vnode.c
--- a/sys/uvm/uvm_vnode.c       Fri Dec 02 16:54:32 2011 +0000
+++ b/sys/uvm/uvm_vnode.c       Tue Dec 20 13:46:17 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: uvm_vnode.c,v 1.97.2.2 2011/11/26 15:19:06 yamt Exp $  */
+/*     $NetBSD: uvm_vnode.c,v 1.97.2.3 2011/12/20 13:46:17 yamt Exp $  */
 
 /*
  * Copyright (c) 1997 Charles D. Cranor and Washington University.
@@ -45,7 +45,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uvm_vnode.c,v 1.97.2.2 2011/11/26 15:19:06 yamt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uvm_vnode.c,v 1.97.2.3 2011/12/20 13:46:17 yamt Exp $");
 
 #include "opt_uvmhist.h"
 
@@ -77,7 +77,8 @@
 static void    uvn_reference(struct uvm_object *);
 
 static int     uvn_findpage(struct uvm_object *, voff_t, struct vm_page **,
-                            int, struct uvm_page_array *a, unsigned int);
+                            unsigned int, struct uvm_page_array *a,
+                            unsigned int);
 
 /*
  * master pager structure
@@ -193,18 +194,22 @@
  */
 
 int
-uvn_findpages(struct uvm_object *uobj, voff_t offset, int *npagesp,
-    struct vm_page **pgs, int flags)
+uvn_findpages(struct uvm_object *uobj, voff_t offset, unsigned int *npagesp,
+    struct vm_page **pgs, struct uvm_page_array *a, unsigned int flags)
 {
-       int i, count, found, npages, rv;
-       struct uvm_page_array a;
+       unsigned int count, found, npages;
+       int i, rv;
+       struct uvm_page_array a_store;
 
-       uvm_page_array_init(&a);
+       if (a == NULL) {
+               a = &a_store;
+               uvm_page_array_init(a);
+       }
        count = found = 0;
        npages = *npagesp;
        if (flags & UFP_BACKWARD) {
                for (i = npages - 1; i >= 0; i--, offset -= PAGE_SIZE) {
-                       rv = uvn_findpage(uobj, offset, &pgs[i], flags, &a,
+                       rv = uvn_findpage(uobj, offset, &pgs[i], flags, a,
                            npages - i);
                        if (rv == 0) {
                                if (flags & UFP_DIRTYONLY)
@@ -215,7 +220,7 @@
                }
        } else {
                for (i = 0; i < npages; i++, offset += PAGE_SIZE) {
-                       rv = uvn_findpage(uobj, offset, &pgs[i], flags, &a,
+                       rv = uvn_findpage(uobj, offset, &pgs[i], flags, a,
                            npages - i);
                        if (rv == 0) {
                                if (flags & UFP_DIRTYONLY)
@@ -225,14 +230,16 @@
                        count++;
                }
        }
-       uvm_page_array_fini(&a);
+       if (a == &a_store) {
+               uvm_page_array_fini(a);
+       }
        *npagesp = count;
        return (found);
 }
 
 static int
 uvn_findpage(struct uvm_object *uobj, voff_t offset, struct vm_page **pgp,
-    int flags, struct uvm_page_array *a, unsigned int nleft)
+    unsigned int flags, struct uvm_page_array *a, unsigned int nleft)
 {
        struct vm_page *pg;
        bool dirty;
@@ -311,6 +318,20 @@
                        goto skip;
                }



Home | Main Index | Thread Index | Old Index