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,"

Reply via email to