Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/yamt-pagecache]: src/sys/uvm - track the number of clean/dirty/unknown p...
details: https://anonhg.NetBSD.org/src/rev/cdbc9097c8e1
branches: yamt-pagecache
changeset: 770824:cdbc9097c8e1
user: yamt <yamt%NetBSD.org@localhost>
date: Fri Nov 11 10:34:24 2011 +0000
description:
- track the number of clean/dirty/unknown pages in the system.
- g/c PG_MARKER
diffstat:
sys/uvm/uvm.h | 4 +++-
sys/uvm/uvm_extern.h | 5 ++++-
sys/uvm/uvm_meter.c | 10 ++++++++--
sys/uvm/uvm_page.c | 18 +++++++++++++++---
sys/uvm/uvm_page.h | 31 +++++++++++++++++++------------
sys/uvm/uvm_page_status.c | 42 +++++++++++++++++++++++++++++++++---------
6 files changed, 82 insertions(+), 28 deletions(-)
diffs (truncated from 307 to 300 lines):
diff -r 01b2985759ac -r cdbc9097c8e1 sys/uvm/uvm.h
--- a/sys/uvm/uvm.h Thu Nov 10 23:51:17 2011 +0000
+++ b/sys/uvm/uvm.h Fri Nov 11 10:34:24 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: uvm.h,v 1.62 2011/05/17 04:18:07 mrg Exp $ */
+/* $NetBSD: uvm.h,v 1.62.4.1 2011/11/11 10:34:24 yamt Exp $ */
/*
* Copyright (c) 1997 Charles D. Cranor and Washington University.
@@ -81,6 +81,8 @@
pages in the idle loop */
int pages[PGFL_NQUEUES]; /* total of pages in page_free */
u_int emap_gen; /* emap generation number */
+
+ int64_t pagestate[UVM_PAGE_NUM_STATUS];
};
/*
diff -r 01b2985759ac -r cdbc9097c8e1 sys/uvm/uvm_extern.h
--- a/sys/uvm/uvm_extern.h Thu Nov 10 23:51:17 2011 +0000
+++ b/sys/uvm/uvm_extern.h Fri Nov 11 10:34:24 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: uvm_extern.h,v 1.176 2011/09/01 06:40:28 matt Exp $ */
+/* $NetBSD: uvm_extern.h,v 1.176.2.1 2011/11/11 10:34:24 yamt Exp $ */
/*
* Copyright (c) 1997 Charles D. Cranor and Washington University.
@@ -456,6 +456,9 @@
int64_t colorhit;
int64_t colormiss;
int64_t ncolors;
+ int64_t mightdirtypages;
+ int64_t cleanpages;
+ int64_t dirtypages;
};
#ifdef _KERNEL
diff -r 01b2985759ac -r cdbc9097c8e1 sys/uvm/uvm_meter.c
--- a/sys/uvm/uvm_meter.c Thu Nov 10 23:51:17 2011 +0000
+++ b/sys/uvm/uvm_meter.c Fri Nov 11 10:34:24 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: uvm_meter.c,v 1.56 2011/02/02 15:25:27 chuck Exp $ */
+/* $NetBSD: uvm_meter.c,v 1.56.4.1 2011/11/11 10:34:24 yamt Exp $ */
/*
* Copyright (c) 1997 Charles D. Cranor and Washington University.
@@ -36,7 +36,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uvm_meter.c,v 1.56 2011/02/02 15:25:27 chuck Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uvm_meter.c,v 1.56.4.1 2011/11/11 10:34:24 yamt Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -176,7 +176,13 @@
u.colormiss = uvmexp.colormiss;
u.cpuhit = uvmexp.cpuhit;
u.cpumiss = uvmexp.cpumiss;
+ for (CPU_INFO_FOREACH(cii, ci)) {
+ struct uvm_cpu *ucpu = ci->ci_data.cpu_uvm;
+ u.mightdirtypages += ucpu->pagestate[UVM_PAGE_STATUS_UNKNOWN];
+ u.cleanpages += ucpu->pagestate[UVM_PAGE_STATUS_CLEAN];
+ u.dirtypages += ucpu->pagestate[UVM_PAGE_STATUS_DIRTY];
+ }
node = *rnode;
node.sysctl_data = &u;
node.sysctl_size = sizeof(u);
diff -r 01b2985759ac -r cdbc9097c8e1 sys/uvm/uvm_page.c
--- a/sys/uvm/uvm_page.c Thu Nov 10 23:51:17 2011 +0000
+++ b/sys/uvm/uvm_page.c Fri Nov 11 10:34:24 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: uvm_page.c,v 1.178.2.2 2011/11/06 22:05:00 yamt Exp $ */
+/* $NetBSD: uvm_page.c,v 1.178.2.3 2011/11/11 10:34:24 yamt Exp $ */
/*
* Copyright (c) 1997 Charles D. Cranor and Washington University.
@@ -66,7 +66,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uvm_page.c,v 1.178.2.2 2011/11/06 22:05:00 yamt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uvm_page.c,v 1.178.2.3 2011/11/11 10:34:24 yamt Exp $");
#include "opt_ddb.h"
#include "opt_uvmhist.h"
@@ -423,7 +423,15 @@
if (atop(paddr) >= seg->avail_start &&
atop(paddr) < seg->avail_end) {
uvmexp.npages++;
- /* add page to free pool */
+ /*
+ * add page to free pool
+ *
+ * adjust pagestate[] so that it won't go
+ * negative.
+ */
+ KASSERT(uvm_pagegetdirty(&seg->pgs[i])
+ == UVM_PAGE_STATUS_UNKNOWN);
+ boot_cpu.pagestate[UVM_PAGE_STATUS_UNKNOWN]++;
uvm_pagefree(&seg->pgs[i]);
}
}
@@ -1308,6 +1316,7 @@
* otherwise we race with uvm_pglistalloc.
*/
pg->pqflags = 0;
+ ucpu->pagestate[UVM_PAGE_STATUS_CLEAN]++;
mutex_spin_exit(&uvm_fpageqlock);
if (anon) {
anon->an_page = pg;
@@ -1470,6 +1479,7 @@
struct pgflist *pgfl;
struct uvm_cpu *ucpu;
int index, color, queue;
+ unsigned int status;
bool iszero;
#ifdef DEBUG
@@ -1568,6 +1578,7 @@
color = VM_PGCOLOR_BUCKET(pg);
queue = (iszero ? PGFL_ZEROS : PGFL_UNKNOWN);
+ status = uvm_pagegetdirty(pg);
#ifdef DEBUG
pg->uobject = (void *)0xdeadbeef;
pg->uanon = (void *)0xdeadbeef;
@@ -1599,6 +1610,7 @@
if (ucpu->pages[PGFL_ZEROS] < ucpu->pages[PGFL_UNKNOWN]) {
ucpu->page_idle_zero = vm_page_zero_enable;
}
+ ucpu->pagestate[status]--;
mutex_spin_exit(&uvm_fpageqlock);
}
diff -r 01b2985759ac -r cdbc9097c8e1 sys/uvm/uvm_page.h
--- a/sys/uvm/uvm_page.h Thu Nov 10 23:51:17 2011 +0000
+++ b/sys/uvm/uvm_page.h Fri Nov 11 10:34:24 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: uvm_page.h,v 1.73.2.2 2011/11/06 22:05:00 yamt Exp $ */
+/* $NetBSD: uvm_page.h,v 1.73.2.3 2011/11/11 10:34:24 yamt Exp $ */
/*
* Copyright (c) 1997 Charles D. Cranor and Washington University.
@@ -163,26 +163,29 @@
* PG_RDONLY and PG_HOLE acts like a "read-only count". ie. either of
* them is set, the page should not be mapped writably. typically
* they are set by pgo_get to inform the fault handler.
+ *
+ * if you want to renumber PG_CLEAN and PG_DIRTY, check __CTASSERTs in
+ * uvm_page_status.c first.
*/
-#define PG_BUSY 0x0001 /* page is locked */
-#define PG_WANTED 0x0002 /* someone is waiting for page */
-#define PG_TABLED 0x0004 /* page is in VP table */
-#define PG_CLEAN 0x0008 /* page is known clean */
+#define PG_CLEAN 0x0001 /* page is known clean */
+#define PG_DIRTY 0x0002 /* page is known dirty */
+#define PG_BUSY 0x0004 /* page is locked */
+#define PG_WANTED 0x0008 /* someone is waiting for page */
#define PG_PAGEOUT 0x0010 /* page to be freed for pagedaemon */
#define PG_RELEASED 0x0020 /* page to be freed when unbusied */
#define PG_FAKE 0x0040 /* page is not yet initialized */
#define PG_RDONLY 0x0080 /* page must be mapped read-only */
#define PG_ZERO 0x0100 /* page is pre-zero'd */
-#define PG_MARKER 0x0200 /* dummy marker page */
-#define PG_DIRTY 0x0400 /* page is known dirty */
-#define PG_HOLE 0x0800 /* XXX */
+#define PG_TABLED 0x0200 /* page is in VP table */
+#define PG_HOLE 0x0400 /* XXX */
#define PG_PAGER1 0x1000 /* pager-specific flag */
#define UVM_PGFLAGBITS \
- "\20\1BUSY\2WANTED\3TABLED\4CLEAN\5PAGEOUT\6RELEASED\7FAKE\10RDONLY" \
- "\11ZERO\12MARKER\13DIRTY\15PAGER1"
+ "\20\1CLEAN\2DIRTY\3BUSY\4WANTED" \
+ "\5PAGEOUT\6RELEASED\7FAKE\10RDONLY" \
+ "\11ZERO\12TABLED\13HOLE"
#define PQ_FREE 0x0001 /* page is on free list */
#define PQ_ANON 0x0002 /* page is part of an anon, rather
@@ -301,10 +304,14 @@
* dirty or not.
* basically, UVM_PAGE_STATUS_CLEAN implies that the page has no writable
* mapping.
+ *
+ * if you want to renumber these, check __CTASSERTs in
+ * uvm_page_status.c first.
*/
-#define UVM_PAGE_STATUS_DIRTY (PG_DIRTY)
#define UVM_PAGE_STATUS_UNKNOWN 0
-#define UVM_PAGE_STATUS_CLEAN (PG_CLEAN)
+#define UVM_PAGE_STATUS_CLEAN 1
+#define UVM_PAGE_STATUS_DIRTY 2
+#define UVM_PAGE_NUM_STATUS 3
int uvm_page_lookup_freelist(struct vm_page *);
diff -r 01b2985759ac -r cdbc9097c8e1 sys/uvm/uvm_page_status.c
--- a/sys/uvm/uvm_page_status.c Thu Nov 10 23:51:17 2011 +0000
+++ b/sys/uvm/uvm_page_status.c Fri Nov 11 10:34:24 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: uvm_page_status.c,v 1.1.2.1 2011/11/02 21:55:39 yamt Exp $ */
+/* $NetBSD: uvm_page_status.c,v 1.1.2.2 2011/11/11 10:34:24 yamt Exp $ */
/*-
* Copyright (c)2011 YAMAMOTO Takashi,
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uvm_page_status.c,v 1.1.2.1 2011/11/02 21:55:39 yamt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uvm_page_status.c,v 1.1.2.2 2011/11/11 10:34:24 yamt Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -41,6 +41,15 @@
*/
/*
+ * these constants are chosen to match so that we can convert between
+ * them quickly.
+ */
+
+__CTASSERT(UVM_PAGE_STATUS_UNKNOWN == 0);
+__CTASSERT(UVM_PAGE_STATUS_DIRTY == PG_DIRTY);
+__CTASSERT(UVM_PAGE_STATUS_CLEAN == PG_CLEAN);
+
+/*
* uvm_pagegetdirty: return the dirtiness status (one of UVM_PAGE_STATUS_
* values) of the page.
*/
@@ -58,24 +67,38 @@
return pg->flags & (PG_CLEAN|PG_DIRTY);
}
+static void
+stat_update(unsigned int oldstatus, unsigned int newstatus)
+{
+ struct uvm_cpu *ucpu;
+
+ KASSERT(oldstatus != newstatus);
+ kpreempt_disable();
+ ucpu = curcpu()->ci_data.cpu_uvm;
+ ucpu->pagestate[oldstatus]--;
+ ucpu->pagestate[newstatus]++;
+ kpreempt_enable();
+}
+
/*
* uvm_pagemarkdirty: set the dirtiness status (one of UVM_PAGE_STATUS_ values)
* of the page.
*/
void
-uvm_pagemarkdirty(struct vm_page *pg, unsigned int status)
+uvm_pagemarkdirty(struct vm_page *pg, unsigned int newstatus)
{
struct uvm_object * const uobj = pg->uobject;
const uint64_t idx = pg->offset >> PAGE_SHIFT;
+ const unsigned int oldstatus = uvm_pagegetdirty(pg);
- KASSERT((~status & (PG_CLEAN|PG_DIRTY)) != 0);
- KASSERT((status & ~(PG_CLEAN|PG_DIRTY)) == 0);
+ KASSERT((~newstatus & (PG_CLEAN|PG_DIRTY)) != 0);
+ KASSERT((newstatus & ~(PG_CLEAN|PG_DIRTY)) == 0);
KASSERT(uvm_page_locked_p(pg));
KASSERT(uobj == NULL || ((pg->flags & PG_CLEAN) == 0) ==
radix_tree_get_tag(&uobj->uo_pages, idx, UVM_PAGE_DIRTY_TAG));
- if (uvm_pagegetdirty(pg) == status) {
+ if (oldstatus == newstatus) {
return;
}
/*
@@ -83,7 +106,7 @@
* find possibly-dirty pages quickly.
*/
if (uobj != NULL) {
- if (status == UVM_PAGE_STATUS_CLEAN) {
+ if (newstatus == UVM_PAGE_STATUS_CLEAN) {
radix_tree_clear_tag(&uobj->uo_pages, idx,
UVM_PAGE_DIRTY_TAG);
} else {
@@ -91,16 +114,17 @@
UVM_PAGE_DIRTY_TAG);
}
}
- if (status == UVM_PAGE_STATUS_UNKNOWN) {
+ if (newstatus == UVM_PAGE_STATUS_UNKNOWN) {
/*
* start relying on pmap-level dirtiness tracking.
*/
pmap_clear_modify(pg);
}
pg->flags &= ~(PG_CLEAN|PG_DIRTY);
- pg->flags |= status;
Home |
Main Index |
Thread Index |
Old Index