Module Name: src Committed By: uebayasi Date: Mon Nov 15 17:32:02 UTC 2010
Modified Files: src/sys/miscfs/genfs [uebayasi-xip]: genfs_io.c src/sys/uvm [uebayasi-xip]: uvm_page.c uvm_page.h Log Message: Move zero-page into a common place, in the hope that it's shared for other purposes. According to Chuck Silvers, zero-page mappings don't need to be explicitly unmapped in putpages(). Follow that advice. To generate a diff of this commit: cvs rdiff -u -r1.36.2.30 -r1.36.2.31 src/sys/miscfs/genfs/genfs_io.c cvs rdiff -u -r1.153.2.64 -r1.153.2.65 src/sys/uvm/uvm_page.c cvs rdiff -u -r1.59.2.35 -r1.59.2.36 src/sys/uvm/uvm_page.h 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.36.2.30 src/sys/miscfs/genfs/genfs_io.c:1.36.2.31 --- src/sys/miscfs/genfs/genfs_io.c:1.36.2.30 Sat Nov 6 08:08:44 2010 +++ src/sys/miscfs/genfs/genfs_io.c Mon Nov 15 17:32:01 2010 @@ -1,4 +1,4 @@ -/* $NetBSD: genfs_io.c,v 1.36.2.30 2010/11/06 08:08:44 uebayasi Exp $ */ +/* $NetBSD: genfs_io.c,v 1.36.2.31 2010/11/15 17:32:01 uebayasi Exp $ */ /* * Copyright (c) 1982, 1986, 1989, 1993 @@ -31,7 +31,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: genfs_io.c,v 1.36.2.30 2010/11/06 08:08:44 uebayasi Exp $"); +__KERNEL_RCSID(0, "$NetBSD: genfs_io.c,v 1.36.2.31 2010/11/15 17:32:01 uebayasi Exp $"); #include "opt_xip.h" @@ -873,18 +873,8 @@ * allocated and linearly ordered by physical address. */ if (blkno < 0) { - zero_page = uvm_pagelookup(uobj, 0); - - if (zero_page == NULL) { - mutex_enter(&uobj->vmobjlock); - zero_page = uvm_pagealloc(uobj, 0, NULL, - UVM_PGA_ZERO); - mutex_exit(&uobj->vmobjlock); - KASSERT(zero_page != NULL); - mutex_enter(&uvm_pageqlock); - uvm_pagewire(zero_page); - mutex_exit(&uvm_pageqlock); - } + zero_page = uvm_page_zeropage_alloc(); + KASSERT(zero_page != NULL); pps[i] = zero_page; } else { struct vm_physseg *seg; @@ -918,10 +908,10 @@ for (i = 0; i < npages; i++) { struct vm_page *pg = pps[i]; + KASSERT((pg->flags & PG_RDONLY) != 0); if (pg == zero_page) { } else { KASSERT((pg->flags & PG_BUSY) == 0); - KASSERT((pg->flags & PG_RDONLY) != 0); KASSERT((pg->flags & PG_CLEAN) != 0); KASSERT((pg->flags & PG_DEVICE) != 0); pg->flags |= PG_BUSY; @@ -1544,8 +1534,8 @@ pg = pgs[i]; if (pg == NULL || pg == PGO_DONTCARE) continue; - if (pg == zero_page) { - put_zero_page = true; + if (pg == uvm_page_zeropage) { + /* Do nothing for holes. */ } else { /* * Freeing normal XIP pages; nothing to do. @@ -1562,17 +1552,6 @@ off += npages << PAGE_SHIFT; } - if (put_zero_page) { - /* - * Freeing an XIP zero page. - */ - pmap_page_protect(zero_page, VM_PROT_NONE); - mutex_enter(&uvm_pageqlock); - uvm_pageunwire(zero_page); - mutex_exit(&uvm_pageqlock); - uvm_pagefree(zero_page); - } - KASSERT(uobj->uo_npages == 0); done: Index: src/sys/uvm/uvm_page.c diff -u src/sys/uvm/uvm_page.c:1.153.2.64 src/sys/uvm/uvm_page.c:1.153.2.65 --- src/sys/uvm/uvm_page.c:1.153.2.64 Fri Nov 12 19:02:44 2010 +++ src/sys/uvm/uvm_page.c Mon Nov 15 17:32:01 2010 @@ -1,4 +1,4 @@ -/* $NetBSD: uvm_page.c,v 1.153.2.64 2010/11/12 19:02:44 uebayasi Exp $ */ +/* $NetBSD: uvm_page.c,v 1.153.2.65 2010/11/15 17:32:01 uebayasi Exp $ */ /* * Copyright (c) 2010 The NetBSD Foundation, Inc. @@ -97,7 +97,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: uvm_page.c,v 1.153.2.64 2010/11/12 19:02:44 uebayasi Exp $"); +__KERNEL_RCSID(0, "$NetBSD: uvm_page.c,v 1.153.2.65 2010/11/15 17:32:01 uebayasi Exp $"); #include "opt_ddb.h" #include "opt_uvmhist.h" @@ -113,6 +113,7 @@ #include <sys/proc.h> #include <sys/atomic.h> #include <sys/cpu.h> +#include <sys/once.h> #include <uvm/uvm.h> #include <uvm/uvm_ddb.h> @@ -2234,6 +2235,46 @@ return (VM_PHYSMEM_PTR(lcv)->free_list); } +static int uvm_page_zeropage_init(void); + +struct vm_page *uvm_page_zeropage; + +struct vm_page * +uvm_page_zeropage_alloc(void) +{ + static ONCE_DECL(inited); + + (void)RUN_ONCE(&inited, uvm_page_zeropage_init); + KASSERT(uvm_page_zeropage != NULL); + return uvm_page_zeropage; +} + +static int +uvm_page_zeropage_init(void) +{ + struct pglist mlist; + struct vm_page *pg; + int n; + + n = uvm_pglistalloc(PAGE_SIZE, 0, -1, PAGE_SIZE, PAGE_SIZE, + &mlist, 1, 1); + KASSERT(n == 1); + + pg = TAILQ_FIRST(&mlist); + KASSERT(pg != NULL); + + pmap_zero_page(VM_PAGE_TO_PHYS(pg)); + + pg->flags |= PG_RDONLY; + + mutex_enter(&uvm_pageqlock); + uvm_pagewire(pg); + mutex_exit(&uvm_pageqlock); + + uvm_page_zeropage = pg; + return 0; +} + #if defined(DDB) || defined(DEBUGPRINT) /* Index: src/sys/uvm/uvm_page.h diff -u src/sys/uvm/uvm_page.h:1.59.2.35 src/sys/uvm/uvm_page.h:1.59.2.36 --- src/sys/uvm/uvm_page.h:1.59.2.35 Fri Nov 12 08:13:40 2010 +++ src/sys/uvm/uvm_page.h Mon Nov 15 17:32:01 2010 @@ -1,4 +1,4 @@ -/* $NetBSD: uvm_page.h,v 1.59.2.35 2010/11/12 08:13:40 uebayasi Exp $ */ +/* $NetBSD: uvm_page.h,v 1.59.2.36 2010/11/15 17:32:01 uebayasi Exp $ */ /* * Copyright (c) 1997 Charles D. Cranor and Washington University. @@ -311,6 +311,9 @@ int uvm_page_lookup_freelist(struct vm_page *); +extern struct vm_page *uvm_page_zeropage; +struct vm_page *uvm_page_zeropage_alloc(void); + int vm_physseg_find(paddr_t, int *); struct vm_page *uvm_phys_to_vm_page(paddr_t); paddr_t uvm_vm_page_to_phys(const struct vm_page *);