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);

Reply via email to