Module Name: src
Committed By: matt
Date: Thu Apr 12 01:40:27 UTC 2012
Modified Files:
src/sys/uvm [matt-nb5-mips64]: uvm_extern.h uvm_fault.c uvm_km.c
uvm_meter.c uvm_pdaemon.c uvm_pdaemon.h uvm_pdpolicy.h
uvm_pdpolicy_clock.c uvm_stat.c
Log Message:
Separate object-less anon pages out of the active list if there is no swap
device. Make uvm_reclaimable and uvm.*estimatable understand colors and
kmem allocations.
To generate a diff of this commit:
cvs rdiff -u -r1.148.4.2.4.5 -r1.148.4.2.4.6 src/sys/uvm/uvm_extern.h
cvs rdiff -u -r1.125.6.1.4.4 -r1.125.6.1.4.5 src/sys/uvm/uvm_fault.c
cvs rdiff -u -r1.101.4.2.4.9 -r1.101.4.2.4.10 src/sys/uvm/uvm_km.c
cvs rdiff -u -r1.49.16.3 -r1.49.16.4 src/sys/uvm/uvm_meter.c
cvs rdiff -u -r1.93.4.2.4.8 -r1.93.4.2.4.9 src/sys/uvm/uvm_pdaemon.c
cvs rdiff -u -r1.15 -r1.15.28.1 src/sys/uvm/uvm_pdaemon.h
cvs rdiff -u -r1.3.62.1 -r1.3.62.2 src/sys/uvm/uvm_pdpolicy.h
cvs rdiff -u -r1.12.16.4 -r1.12.16.5 src/sys/uvm/uvm_pdpolicy_clock.c
cvs rdiff -u -r1.31.12.3 -r1.31.12.4 src/sys/uvm/uvm_stat.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/uvm/uvm_extern.h
diff -u src/sys/uvm/uvm_extern.h:1.148.4.2.4.5 src/sys/uvm/uvm_extern.h:1.148.4.2.4.6
--- src/sys/uvm/uvm_extern.h:1.148.4.2.4.5 Thu Feb 9 03:04:59 2012
+++ src/sys/uvm/uvm_extern.h Thu Apr 12 01:40:26 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: uvm_extern.h,v 1.148.4.2.4.5 2012/02/09 03:04:59 matt Exp $ */
+/* $NetBSD: uvm_extern.h,v 1.148.4.2.4.6 2012/04/12 01:40:26 matt Exp $ */
/*
*
@@ -729,7 +729,8 @@ void uvm_aiodone_worker(struct work *,
struct uvm_pggroup;
void uvm_pageout_start(struct uvm_pggroup *, u_int);
void uvm_pageout_done(struct vm_page *, bool);
-void uvm_estimatepageable(u_int *, u_int *);
+void uvm_estimatepageable(const struct uvm_pggroup *,
+ u_int *, u_int *);
/* uvm_pglist.c */
int uvm_pglistalloc(psize_t, paddr_t, paddr_t,
Index: src/sys/uvm/uvm_fault.c
diff -u src/sys/uvm/uvm_fault.c:1.125.6.1.4.4 src/sys/uvm/uvm_fault.c:1.125.6.1.4.5
--- src/sys/uvm/uvm_fault.c:1.125.6.1.4.4 Wed Feb 29 18:03:38 2012
+++ src/sys/uvm/uvm_fault.c Thu Apr 12 01:40:27 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: uvm_fault.c,v 1.125.6.1.4.4 2012/02/29 18:03:38 matt Exp $ */
+/* $NetBSD: uvm_fault.c,v 1.125.6.1.4.5 2012/04/12 01:40:27 matt Exp $ */
/*
*
@@ -39,7 +39,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uvm_fault.c,v 1.125.6.1.4.4 2012/02/29 18:03:38 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uvm_fault.c,v 1.125.6.1.4.5 2012/04/12 01:40:27 matt Exp $");
#include "opt_uvmhist.h"
@@ -369,7 +369,8 @@ uvmfault_anonget(struct uvm_faultinfo *u
uvmexp.fltnoram++;
UVMHIST_LOG(maphist, " noram -- UVM_WAIT",0,
0,0,0);
- if (!uvm_reclaimable()) {
+ if (!uvm_reclaimable(atop(ufi->orig_rvaddr),
+ false)) {
return ENOMEM;
}
uvm_wait("flt_noram1");
@@ -642,7 +643,7 @@ uvmfault_promote(struct uvm_faultinfo *u
uvm_page_unbusy(&uobjpage, 1);
uvmfault_unlockall(ufi, amap, uobj, oanon);
nomem:
- if (!uvm_reclaimable()) {
+ if (!uvm_reclaimable(atop(ufi->orig_rvaddr), false)) {
UVMHIST_LOG(maphist, "out of VM", 0,0,0,0);
uvmexp.fltnoanon++;
error = ENOMEM;
@@ -1405,7 +1406,7 @@ ReFault:
if (anon != oanon)
mutex_exit(&anon->an_lock);
uvmfault_unlockall(&ufi, amap, uobj, oanon);
- if (!uvm_reclaimable()) {
+ if (!uvm_reclaimable(atop(ufi.orig_rvaddr), false)) {
UVMHIST_LOG(maphist,
"<- failed. out of VM",0,0,0,0);
/* XXX instrumentation */
@@ -1790,7 +1791,7 @@ Case2:
pg->flags &= ~(PG_BUSY|PG_FAKE|PG_WANTED);
UVM_PAGE_OWN(pg, NULL, NULL);
uvmfault_unlockall(&ufi, amap, uobj, anon);
- if (!uvm_reclaimable()) {
+ if (!uvm_reclaimable(atop(ufi.orig_rvaddr), false)) {
UVMHIST_LOG(maphist,
"<- failed. out of VM",0,0,0,0);
/* XXX instrumentation */
Index: src/sys/uvm/uvm_km.c
diff -u src/sys/uvm/uvm_km.c:1.101.4.2.4.9 src/sys/uvm/uvm_km.c:1.101.4.2.4.10
--- src/sys/uvm/uvm_km.c:1.101.4.2.4.9 Wed Feb 29 18:03:38 2012
+++ src/sys/uvm/uvm_km.c Thu Apr 12 01:40:27 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: uvm_km.c,v 1.101.4.2.4.9 2012/02/29 18:03:38 matt Exp $ */
+/* $NetBSD: uvm_km.c,v 1.101.4.2.4.10 2012/04/12 01:40:27 matt Exp $ */
/*
* Copyright (c) 1997 Charles D. Cranor and Washington University.
@@ -128,7 +128,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uvm_km.c,v 1.101.4.2.4.9 2012/02/29 18:03:38 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uvm_km.c,v 1.101.4.2.4.10 2012/04/12 01:40:27 matt Exp $");
#include "opt_uvmhist.h"
@@ -618,7 +618,8 @@ uvm_km_alloc(struct vm_map *map, vsize_t
if (__predict_false(pg == NULL)) {
if ((flags & UVM_KMF_NOWAIT) ||
- ((flags & UVM_KMF_CANFAIL) && !uvm_reclaimable())) {
+ ((flags & UVM_KMF_CANFAIL)
+ && !uvm_reclaimable(atop(offset), true))) {
/* free everything! */
uvm_km_free(map, kva, size,
flags & UVM_KMF_TYPEMASK);
Index: src/sys/uvm/uvm_meter.c
diff -u src/sys/uvm/uvm_meter.c:1.49.16.3 src/sys/uvm/uvm_meter.c:1.49.16.4
--- src/sys/uvm/uvm_meter.c:1.49.16.3 Thu Feb 9 03:05:00 2012
+++ src/sys/uvm/uvm_meter.c Thu Apr 12 01:40:27 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: uvm_meter.c,v 1.49.16.3 2012/02/09 03:05:00 matt Exp $ */
+/* $NetBSD: uvm_meter.c,v 1.49.16.4 2012/04/12 01:40:27 matt Exp $ */
/*
* Copyright (c) 1997 Charles D. Cranor and Washington University.
@@ -41,7 +41,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uvm_meter.c,v 1.49.16.3 2012/02/09 03:05:00 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uvm_meter.c,v 1.49.16.4 2012/04/12 01:40:27 matt Exp $");
#include <sys/param.h>
#include <sys/proc.h>
@@ -163,9 +163,9 @@ sysctl_vm_uvmexp2(SYSCTLFN_ARGS)
{
struct sysctlnode node;
struct uvmexp_sysctl u;
- int active, inactive;
+ u_int active = 0, inactive = 0;
- uvm_estimatepageable(&active, &inactive);
+ uvm_estimatepageable(NULL, &active, &inactive);
memset(&u, 0, sizeof(u));
@@ -374,7 +374,7 @@ uvm_total(struct vmtotal *totalp)
struct vm_map *map;
int paging;
#endif
- int active;
+ u_int active = 0;
memset(totalp, 0, sizeof *totalp);
@@ -440,7 +440,7 @@ uvm_total(struct vmtotal *totalp)
/*
* Calculate object memory usage statistics.
*/
- uvm_estimatepageable(&active, NULL);
+ uvm_estimatepageable(NULL, &active, NULL);
totalp->t_free = uvmexp.free;
totalp->t_vm = uvmexp.npages - uvmexp.free + uvmexp.swpginuse;
totalp->t_avm = active + uvmexp.swpginuse; /* XXX */
Index: src/sys/uvm/uvm_pdaemon.c
diff -u src/sys/uvm/uvm_pdaemon.c:1.93.4.2.4.8 src/sys/uvm/uvm_pdaemon.c:1.93.4.2.4.9
--- src/sys/uvm/uvm_pdaemon.c:1.93.4.2.4.8 Wed Feb 29 18:03:40 2012
+++ src/sys/uvm/uvm_pdaemon.c Thu Apr 12 01:40:27 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: uvm_pdaemon.c,v 1.93.4.2.4.8 2012/02/29 18:03:40 matt Exp $ */
+/* $NetBSD: uvm_pdaemon.c,v 1.93.4.2.4.9 2012/04/12 01:40:27 matt Exp $ */
/*
* Copyright (c) 1997 Charles D. Cranor and Washington University.
@@ -71,7 +71,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uvm_pdaemon.c,v 1.93.4.2.4.8 2012/02/29 18:03:40 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uvm_pdaemon.c,v 1.93.4.2.4.9 2012/04/12 01:40:27 matt Exp $");
#include "opt_uvmhist.h"
#include "opt_readahead.h"
@@ -247,8 +247,19 @@ uvm_kick_pdaemon(void)
if (prev_scan_needed != grp->pgrp_scan_needed) {
if (grp->pgrp_scan_needed) {
- TAILQ_INSERT_TAIL(&pdinfo->pd_pendingq,
- grp, pgrp_pending_link);
+ struct uvm_pggroup *prev;
+ TAILQ_FOREACH(prev, &pdinfo->pd_pendingq,
+ pgrp_pending_link) {
+ if (grp->pgrp_free < prev->pgrp_free)
+ break;
+ }
+ if (prev == NULL) {
+ TAILQ_INSERT_TAIL(&pdinfo->pd_pendingq,
+ grp, pgrp_pending_link);
+ } else {
+ TAILQ_INSERT_BEFORE(prev, grp,
+ pgrp_pending_link);
+ }
need_wakeup = true;
} else {
TAILQ_REMOVE(&pdinfo->pd_pendingq,
@@ -542,6 +553,15 @@ uvm_pageout_start(struct uvm_pggroup *gr
uvmpd_checkgroup(grp);
uvmexp.paging += npages;
if (grp->pgrp_paging == 0) {
+ /*
+ * If the group is in a paging queue, it can't be in a pending
+ * queue so remove it if it is.
+ */
+ if (grp->pgrp_scan_needed) {
+ TAILQ_REMOVE(&pdinfo->pd_pendingq, grp,
+ pgrp_pending_link);
+ grp->pgrp_scan_needed = false;
+ }
TAILQ_INSERT_TAIL(&pdinfo->pd_pagingq, grp, pgrp_paging_link);
}
grp->pgrp_paging += npages;
@@ -1200,18 +1220,20 @@ uvmpd_scan(struct uvm_pggroup *grp)
*/
bool
-uvm_reclaimable(void)
+uvm_reclaimable(u_int color, bool kmem_p)
{
- int filepages;
- int active, inactive;
+ u_int filepages, npages;
+ u_int active, inactive;
/*
* if swap is not full, no problem.
*/
+#ifdef VMSWAP
if (!uvm_swapisfull()) {
return true;
}
+#endif
/*
* file-backed pages can be reclaimed even when swap is full.
@@ -1222,11 +1244,31 @@ uvm_reclaimable(void)
* XXX should consider about other reclaimable memory.
* XXX ie. pools, traditional buffer cache.
*/
+ active = 0;
+ inactive = 0;
+ filepages = 0;
+ npages = 0;
+ for (u_int lcv = 0; lcv < VM_NFREELIST; lcv++) {
+ struct uvm_pggroup * const grp =
+ uvm.page_free[color].pgfl_pggroups[lcv];
- filepages = uvmexp.filepages + uvmexp.execpages - uvmexp.wired;
- uvm_estimatepageable(&active, &inactive);
- if (filepages >= MIN((active + inactive) >> 4,
- 5 * 1024 * 1024 >> PAGE_SHIFT)) {
+#ifdef VM_FREELIST_NORMALOK_P
+ /*
+ * If this for kmem and it's a normal freelist, skip it.
+ */
+ if (kmem_p && VM_FREELIST_NORMALOK_P(lcv))
+ continue;
+#endif
+
+ npages += grp->pgrp_npages;
+ filepages += grp->pgrp_filepages + grp->pgrp_execpages;
+ uvm_estimatepageable(grp, &active, &inactive);
+ }
+ filepages -= uvmexp.wired;
+ /*
+ *
+ */
+ if (filepages >= MIN((active + inactive) >> 4, npages / 25)) {
return true;
}
@@ -1238,8 +1280,9 @@ uvm_reclaimable(void)
}
void
-uvm_estimatepageable(u_int *active, u_int *inactive)
+uvm_estimatepageable(const struct uvm_pggroup *grp,
+ u_int *active, u_int *inactive)
{
- uvmpdpol_estimatepageable(active, inactive);
+ uvmpdpol_estimatepageable(grp, active, inactive);
}
Index: src/sys/uvm/uvm_pdaemon.h
diff -u src/sys/uvm/uvm_pdaemon.h:1.15 src/sys/uvm/uvm_pdaemon.h:1.15.28.1
--- src/sys/uvm/uvm_pdaemon.h:1.15 Wed Jan 2 11:49:20 2008
+++ src/sys/uvm/uvm_pdaemon.h Thu Apr 12 01:40:27 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: uvm_pdaemon.h,v 1.15 2008/01/02 11:49:20 ad Exp $ */
+/* $NetBSD: uvm_pdaemon.h,v 1.15.28.1 2012/04/12 01:40:27 matt Exp $ */
/*
* Copyright (c) 1997 Charles D. Cranor and Washington University.
@@ -80,7 +80,7 @@
*/
void uvm_wait(const char *);
-bool uvm_reclaimable(void);
+bool uvm_reclaimable(u_int, bool);
kmutex_t *uvmpd_trylockowner(struct vm_page *);
bool uvmpd_trydropswap(struct vm_page *);
Index: src/sys/uvm/uvm_pdpolicy.h
diff -u src/sys/uvm/uvm_pdpolicy.h:1.3.62.1 src/sys/uvm/uvm_pdpolicy.h:1.3.62.2
--- src/sys/uvm/uvm_pdpolicy.h:1.3.62.1 Thu Feb 9 03:05:01 2012
+++ src/sys/uvm/uvm_pdpolicy.h Thu Apr 12 01:40:27 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: uvm_pdpolicy.h,v 1.3.62.1 2012/02/09 03:05:01 matt Exp $ */
+/* $NetBSD: uvm_pdpolicy.h,v 1.3.62.2 2012/04/12 01:40:27 matt Exp $ */
/*-
* Copyright (c)2005, 2006 YAMAMOTO Takashi,
@@ -40,7 +40,7 @@ size_t uvmpdpol_space(void);
void uvmpdpol_init(void *, size_t);
void uvmpdpol_reinit(void);
void uvmpdpol_recolor(void *, struct uvm_pggroup *, size_t, size_t);
-void uvmpdpol_estimatepageable(u_int *, u_int *);
+void uvmpdpol_estimatepageable(const struct uvm_pggroup *, u_int *, u_int *);
bool uvmpdpol_needsscan_p(struct uvm_pggroup *);
void uvmpdpol_pageactivate(struct vm_page *);
Index: src/sys/uvm/uvm_pdpolicy_clock.c
diff -u src/sys/uvm/uvm_pdpolicy_clock.c:1.12.16.4 src/sys/uvm/uvm_pdpolicy_clock.c:1.12.16.5
--- src/sys/uvm/uvm_pdpolicy_clock.c:1.12.16.4 Fri Feb 17 23:35:31 2012
+++ src/sys/uvm/uvm_pdpolicy_clock.c Thu Apr 12 01:40:27 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: uvm_pdpolicy_clock.c,v 1.12.16.4 2012/02/17 23:35:31 matt Exp $ */
+/* $NetBSD: uvm_pdpolicy_clock.c,v 1.12.16.5 2012/04/12 01:40:27 matt Exp $ */
/* NetBSD: uvm_pdaemon.c,v 1.72 2006/01/05 10:47:33 yamt Exp $ */
/*
@@ -74,7 +74,7 @@
#else /* defined(PDSIM) */
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uvm_pdpolicy_clock.c,v 1.12.16.4 2012/02/17 23:35:31 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uvm_pdpolicy_clock.c,v 1.12.16.5 2012/04/12 01:40:27 matt Exp $");
#include <sys/param.h>
#include <sys/proc.h>
@@ -89,6 +89,7 @@ __KERNEL_RCSID(0, "$NetBSD: uvm_pdpolicy
#define PQ_INACTIVE PQ_PRIVATE1 /* page is in inactive list */
#define PQ_ACTIVE PQ_PRIVATE2 /* page is in active list */
+#define PQ_RADIOACTIVE PQ_PRIVATE3 /* page is in radioactive list */
#if !defined(CLOCK_INACTIVEPCT)
#define CLOCK_INACTIVEPCT 33
@@ -103,7 +104,9 @@ struct uvmpdpol_scanstate {
struct uvmpdpol_groupstate {
struct pglist gs_activeq; /* allocated pages, in use */
struct pglist gs_inactiveq; /* pages between the clock hands */
+ struct pglist gs_radioactiveq; /* allocated pages, in use */
u_int gs_active;
+ u_int gs_radioactive;
u_int gs_inactive;
u_int gs_inactarg;
struct uvmpdpol_scanstate gs_scanstate;
@@ -289,6 +292,18 @@ uvmpdpol_balancequeue(struct uvm_pggroup
//KDASSERT(gs->gs_active == clock_pglist_count(&gs->gs_activeq));
+ /*
+ * If swap was added, move all the pages from radioactive queue to the
+ * active queue.
+ */
+#ifdef VMSWAP
+ if (uvmexp.nswapdev > 0) {
+ while ((pg = TAILQ_FIRST(&gs->gs_radioactiveq)) != NULL) {
+ uvmpdpol_pageactivate(pg);
+ }
+ }
+#endif
+
u_int inactive_shortage = gs->gs_inactarg - gs->gs_inactive;
for (pg = TAILQ_FIRST(&gs->gs_activeq);
pg != NULL && (inactive_shortage > 0 || swap_shortage > 0);
@@ -310,7 +325,6 @@ uvmpdpol_balancequeue(struct uvm_pggroup
/*
* if there's a shortage of inactive pages, deactivate.
*/
-
if (inactive_shortage > 0) {
/* no need to check wire_count as pg is "active" */
uvmpdpol_pagedeactivate(pg);
@@ -328,6 +342,20 @@ uvmpdpol_pagedeactivate(struct vm_page *
struct uvm_pggroup * const grp = uvm_page_to_pggroup(pg);
struct uvmpdpol_groupstate * const gs = grp->pgrp_gs;
+#if 0
+ /*
+ * If there is no swap available and the page is anonymous without
+ * a backing store, don't bother marking it INACTIVE since it would
+ * only be a "dirty reactivation".
+ */
+ if (uvmexp.nswapdev < 1 && pg->uobject == NULL && pg->uanon != NULL) {
+ KASSERT(pg->pqflags & PQ_RADIOACTIVE);
+ return;
+ }
+#else
+ KASSERT((pg->pqflags & PQ_RADIOACTIVE) == 0);
+#endif
+
KASSERT(!(pg->pqflags & PQ_FREE));
KASSERT(mutex_owned(&uvm_pageqlock));
@@ -342,6 +370,17 @@ uvmpdpol_pagedeactivate(struct vm_page *
}
//KDASSERT(gs->gs_active == clock_pglist_count(&gs->gs_activeq));
+ //KDASSERT(gs->gs_radioactive == clock_pglist_count(&gs->gs_radioactiveq));
+
+ if (pg->pqflags & PQ_RADIOACTIVE) {
+ TAILQ_REMOVE(&gs->gs_radioactiveq, pg, pageq.queue);
+ pg->pqflags &= ~PQ_RADIOACTIVE;
+ KASSERT(gs->gs_radioactive > 0);
+ gs->gs_radioactive--;
+ grp->pgrp_active--;
+ }
+
+ //KDASSERT(gs->gs_radioactive == clock_pglist_count(&gs->gs_radioactiveq));
//KDASSERT(gs->gs_inactive == clock_pglist_count(&gs->gs_inactiveq));
if ((pg->pqflags & PQ_INACTIVE) == 0) {
@@ -366,10 +405,16 @@ uvmpdpol_pageactivate(struct vm_page *pg
KASSERT(mutex_owned(&uvm_pageqlock));
uvmpdpol_pagedequeue(pg);
- TAILQ_INSERT_TAIL(&gs->gs_activeq, pg, pageq.queue);
- pg->pqflags |= PQ_ACTIVE;
- gs->gs_active++;
- grp->pgrp_active++;
+ if (uvmexp.nswapdev < 1 && pg->uanon != NULL && pg->uobject == NULL) {
+ TAILQ_INSERT_TAIL(&gs->gs_radioactiveq, pg, pageq.queue);
+ pg->pqflags |= PQ_RADIOACTIVE;
+ gs->gs_radioactive++;
+ } else {
+ TAILQ_INSERT_TAIL(&gs->gs_activeq, pg, pageq.queue);
+ pg->pqflags |= PQ_ACTIVE;
+ gs->gs_active++;
+ grp->pgrp_active++;
+ }
//KDASSERT(gs->gs_active == clock_pglist_count(&gs->gs_activeq));
}
@@ -382,10 +427,20 @@ uvmpdpol_pagedequeue(struct vm_page *pg)
KASSERT(!(pg->pqflags & PQ_FREE));
KASSERT(mutex_owned(&uvm_pageqlock));
+ //KDASSERT(gs->gs_radioactive == clock_pglist_count(&gs->gs_radioactiveq));
+
+ if (pg->pqflags & PQ_RADIOACTIVE) {
+ TAILQ_REMOVE(&gs->gs_radioactiveq, pg, pageq.queue);
+ pg->pqflags &= ~PQ_RADIOACTIVE;
+ KASSERT(gs->gs_radioactive > 0);
+ gs->gs_radioactive--;
+ grp->pgrp_active--;
+ }
+
+ //KDASSERT(gs->gs_radioactive == clock_pglist_count(&gs->gs_radioactiveq));
//KDASSERT(gs->gs_active == clock_pglist_count(&gs->gs_activeq));
if (pg->pqflags & PQ_ACTIVE) {
- KASSERT(mutex_owned(&uvm_pageqlock));
TAILQ_REMOVE(&gs->gs_activeq, pg, pageq.queue);
pg->pqflags &= ~PQ_ACTIVE;
KASSERT(gs->gs_active > 0);
@@ -397,7 +452,6 @@ uvmpdpol_pagedequeue(struct vm_page *pg)
//KDASSERT(gs->gs_inactive == clock_pglist_count(&gs->gs_inactiveq));
if (pg->pqflags & PQ_INACTIVE) {
- KASSERT(mutex_owned(&uvm_pageqlock));
TAILQ_REMOVE(&gs->gs_inactiveq, pg, pageq.queue);
pg->pqflags &= ~PQ_INACTIVE;
KASSERT(gs->gs_inactive > 0);
@@ -424,15 +478,25 @@ bool
uvmpdpol_pageisqueued_p(struct vm_page *pg)
{
- return (pg->pqflags & (PQ_ACTIVE | PQ_INACTIVE)) != 0;
+ return (pg->pqflags & (PQ_RADIOACTIVE | PQ_ACTIVE | PQ_INACTIVE)) != 0;
}
void
-uvmpdpol_estimatepageable(u_int *activep, u_int *inactivep)
+uvmpdpol_estimatepageable(const struct uvm_pggroup *grp,
+ u_int *activep, u_int *inactivep)
{
- struct uvm_pggroup *grp;
- u_int active = 0, inactive = 0;
+ if (grp != NULL) {
+ struct uvmpdpol_groupstate * const gs = grp->pgrp_gs;
+ if (activep) {
+ *activep += gs->gs_active;
+ }
+ if (inactivep) {
+ *inactivep = gs->gs_inactive;
+ }
+ return;
+ }
+ u_int active = 0, inactive = 0;
STAILQ_FOREACH(grp, &uvm.page_groups, pgrp_uvm_link) {
struct uvmpdpol_groupstate * const gs = grp->pgrp_gs;
@@ -486,9 +550,11 @@ uvmpdpol_init(void *new_gs, size_t npggr
for (size_t pggroup = 0; pggroup < npggroups; pggroup++, gs++, grp++) {
TAILQ_INIT(&gs->gs_activeq);
TAILQ_INIT(&gs->gs_inactiveq);
+ TAILQ_INIT(&gs->gs_radioactiveq);
grp->pgrp_gs = gs;
KASSERT(gs->gs_active == 0);
KASSERT(gs->gs_inactive == 0);
+ KASSERT(gs->gs_radioactive == 0);
KASSERT(grp->pgrp_active == 0);
KASSERT(grp->pgrp_inactive == 0);
}
@@ -546,6 +612,7 @@ uvmpdpol_recolor(void *new_gs, struct uv
struct uvmpdpol_groupstate * const dst_gs = &gs[i];
TAILQ_INIT(&dst_gs->gs_activeq);
TAILQ_INIT(&dst_gs->gs_inactiveq);
+ TAILQ_INIT(&dst_gs->gs_radioactiveq);
uvm.pggroups[i].pgrp_gs = dst_gs;
}
@@ -577,6 +644,19 @@ uvmpdpol_recolor(void *new_gs, struct uv
uvm.pggroups[pggroup].pgrp_active++;
}
KASSERT(src_gs->gs_active == 0);
+
+ KDASSERT(src_gs->gs_radioactive == clock_pglist_count(&src_gs->gs_radioactiveq));
+ while ((pg = TAILQ_FIRST(&src_gs->gs_radioactiveq)) != NULL) {
+ u_int pggroup = VM_PAGE_TO_PGGROUP(pg, uvmexp.ncolors);
+ struct uvmpdpol_groupstate * const xgs = &gs[pggroup];
+
+ TAILQ_INSERT_TAIL(&xgs->gs_radioactiveq, pg, pageq.queue);
+ src_gs->gs_radioactive--;
+ xgs->gs_radioactive++;
+ KDASSERT(xgs->gs_radioactive == clock_pglist_count(&xgs->gs_radioactiveq));
+ uvm.pggroups[pggroup].pgrp_active++;
+ }
+ KASSERT(src_gs->gs_active == 0);
}
struct uvm_pggroup *grp;
Index: src/sys/uvm/uvm_stat.c
diff -u src/sys/uvm/uvm_stat.c:1.31.12.3 src/sys/uvm/uvm_stat.c:1.31.12.4
--- src/sys/uvm/uvm_stat.c:1.31.12.3 Thu Feb 16 04:20:46 2012
+++ src/sys/uvm/uvm_stat.c Thu Apr 12 01:40:27 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: uvm_stat.c,v 1.31.12.3 2012/02/16 04:20:46 matt Exp $ */
+/* $NetBSD: uvm_stat.c,v 1.31.12.4 2012/04/12 01:40:27 matt Exp $ */
/*
*
@@ -39,7 +39,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uvm_stat.c,v 1.31.12.3 2012/02/16 04:20:46 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uvm_stat.c,v 1.31.12.4 2012/04/12 01:40:27 matt Exp $");
#include "opt_uvmhist.h"
#include "opt_readahead.h"
@@ -211,7 +211,7 @@ uvmexp_print(void (*pr)(const char *, ..
struct uvm_pggroup *grp;
int active, inactive;
- uvm_estimatepageable(&active, &inactive);
+ uvm_estimatepageable(NULL, &active, &inactive);
(*pr)("Current UVM status:\n");
(*pr)(" pagesize=%d (0x%x), pagemask=0x%x, pageshift=%d,"