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