Module Name: src Committed By: yamt Date: Tue Dec 20 13:46:17 UTC 2011
Modified Files: src/sys/miscfs/genfs [yamt-pagecache]: genfs_io.c src/sys/uvm [yamt-pagecache]: uvm_extern.h uvm_vnode.c Log Message: don't inline uvn_findpages in genfs_io. To generate a diff of this commit: cvs rdiff -u -r1.53.2.5 -r1.53.2.6 src/sys/miscfs/genfs/genfs_io.c cvs rdiff -u -r1.176.2.4 -r1.176.2.5 src/sys/uvm/uvm_extern.h cvs rdiff -u -r1.97.2.2 -r1.97.2.3 src/sys/uvm/uvm_vnode.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/miscfs/genfs/genfs_io.c diff -u src/sys/miscfs/genfs/genfs_io.c:1.53.2.5 src/sys/miscfs/genfs/genfs_io.c:1.53.2.6 --- src/sys/miscfs/genfs/genfs_io.c:1.53.2.5 Wed Nov 30 14:31:29 2011 +++ src/sys/miscfs/genfs/genfs_io.c Tue Dec 20 13:46:17 2011 @@ -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 @@ startover: } #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 @@ startover: 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 @@ startover: 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 @@ genfs_do_putpages(struct vnode *vp, off_ 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 @@ retry: */ 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 @@ retry: 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 @@ retry: /* * 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 @@ genfs_compat_getpages(void *v) 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 @@ genfs_compat_getpages(void *v) 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); Index: src/sys/uvm/uvm_extern.h diff -u src/sys/uvm/uvm_extern.h:1.176.2.4 src/sys/uvm/uvm_extern.h:1.176.2.5 --- src/sys/uvm/uvm_extern.h:1.176.2.4 Sun Nov 20 10:52:33 2011 +++ src/sys/uvm/uvm_extern.h Tue Dec 20 13:46:17 2011 @@ -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 @@ typedef voff_t pgoff_t; /* XXX: number #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 @@ int uvm_grow(struct proc *, vaddr_t); 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 *); Index: src/sys/uvm/uvm_vnode.c diff -u src/sys/uvm/uvm_vnode.c:1.97.2.2 src/sys/uvm/uvm_vnode.c:1.97.2.3 --- src/sys/uvm/uvm_vnode.c:1.97.2.2 Sat Nov 26 15:19:06 2011 +++ src/sys/uvm/uvm_vnode.c Tue Dec 20 13:46:17 2011 @@ -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 int uvn_put(struct uvm_object *, 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 @@ uvn_get(struct uvm_object *uobj, voff_t */ 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; - - uvm_page_array_init(&a); + unsigned int count, found, npages; + int i, rv; + struct uvm_page_array a_store; + + 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 @@ uvn_findpages(struct uvm_object *uobj, v } } 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 @@ uvn_findpages(struct uvm_object *uobj, v 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 @@ uvn_findpage(struct uvm_object *uobj, vo goto skip; } + /* + * check for PG_PAGER1 requests + */ + if ((flags & UFP_NOPAGER1) != 0 && + (pg->flags & PG_PAGER1) != 0) { + UVMHIST_LOG(ubchist, "nopager1",0,0,0,0); + goto skip; + } + if ((flags & UFP_ONLYPAGER1) != 0 && + (pg->flags & PG_PAGER1) == 0) { + UVMHIST_LOG(ubchist, "onlypager1",0,0,0,0); + goto skip; + } + /* stop on clean pages if requested */ if (flags & UFP_DIRTYONLY) { dirty = uvm_pagecheckdirty(pg, false);