Mon Jan 30 17:22:01 2012 UTC ()
removed code from uvmpdpol_needsscan_p that got there by mistake
pointed out by yamt@


(para)
diff -r1.16 -r1.17 src/sys/uvm/uvm_pdpolicy_clock.c

cvs diff -r1.16 -r1.17 src/sys/uvm/uvm_pdpolicy_clock.c (switch to unified diff)

--- src/sys/uvm/uvm_pdpolicy_clock.c 2012/01/28 00:00:06 1.16
+++ src/sys/uvm/uvm_pdpolicy_clock.c 2012/01/30 17:21:52 1.17
@@ -1,494 +1,480 @@ @@ -1,494 +1,480 @@
1/* $NetBSD: uvm_pdpolicy_clock.c,v 1.16 2012/01/28 00:00:06 rmind Exp $ */ 1/* $NetBSD: uvm_pdpolicy_clock.c,v 1.17 2012/01/30 17:21:52 para Exp $ */
2/* NetBSD: uvm_pdaemon.c,v 1.72 2006/01/05 10:47:33 yamt Exp $ */ 2/* NetBSD: uvm_pdaemon.c,v 1.72 2006/01/05 10:47:33 yamt Exp $ */
3 3
4/* 4/*
5 * Copyright (c) 1997 Charles D. Cranor and Washington University. 5 * Copyright (c) 1997 Charles D. Cranor and Washington University.
6 * Copyright (c) 1991, 1993, The Regents of the University of California. 6 * Copyright (c) 1991, 1993, The Regents of the University of California.
7 * 7 *
8 * All rights reserved. 8 * All rights reserved.
9 * 9 *
10 * This code is derived from software contributed to Berkeley by 10 * This code is derived from software contributed to Berkeley by
11 * The Mach Operating System project at Carnegie-Mellon University. 11 * The Mach Operating System project at Carnegie-Mellon University.
12 * 12 *
13 * Redistribution and use in source and binary forms, with or without 13 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions 14 * modification, are permitted provided that the following conditions
15 * are met: 15 * are met:
16 * 1. Redistributions of source code must retain the above copyright 16 * 1. Redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer. 17 * notice, this list of conditions and the following disclaimer.
18 * 2. Redistributions in binary form must reproduce the above copyright 18 * 2. Redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the 19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the distribution. 20 * documentation and/or other materials provided with the distribution.
21 * 3. Neither the name of the University nor the names of its contributors 21 * 3. Neither the name of the University nor the names of its contributors
22 * may be used to endorse or promote products derived from this software 22 * may be used to endorse or promote products derived from this software
23 * without specific prior written permission. 23 * without specific prior written permission.
24 * 24 *
25 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 25 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 28 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 * SUCH DAMAGE. 35 * SUCH DAMAGE.
36 * 36 *
37 * @(#)vm_pageout.c 8.5 (Berkeley) 2/14/94 37 * @(#)vm_pageout.c 8.5 (Berkeley) 2/14/94
38 * from: Id: uvm_pdaemon.c,v 1.1.2.32 1998/02/06 05:26:30 chs Exp 38 * from: Id: uvm_pdaemon.c,v 1.1.2.32 1998/02/06 05:26:30 chs Exp
39 * 39 *
40 * 40 *
41 * Copyright (c) 1987, 1990 Carnegie-Mellon University. 41 * Copyright (c) 1987, 1990 Carnegie-Mellon University.
42 * All rights reserved. 42 * All rights reserved.
43 * 43 *
44 * Permission to use, copy, modify and distribute this software and 44 * Permission to use, copy, modify and distribute this software and
45 * its documentation is hereby granted, provided that both the copyright 45 * its documentation is hereby granted, provided that both the copyright
46 * notice and this permission notice appear in all copies of the 46 * notice and this permission notice appear in all copies of the
47 * software, derivative works or modified versions, and any portions 47 * software, derivative works or modified versions, and any portions
48 * thereof, and that both notices appear in supporting documentation. 48 * thereof, and that both notices appear in supporting documentation.
49 * 49 *
50 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 50 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
51 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND 51 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
52 * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 52 * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
53 * 53 *
54 * Carnegie Mellon requests users of this software to return to 54 * Carnegie Mellon requests users of this software to return to
55 * 55 *
56 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 56 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
57 * School of Computer Science 57 * School of Computer Science
58 * Carnegie Mellon University 58 * Carnegie Mellon University
59 * Pittsburgh PA 15213-3890 59 * Pittsburgh PA 15213-3890
60 * 60 *
61 * any improvements or extensions that they make and grant Carnegie the 61 * any improvements or extensions that they make and grant Carnegie the
62 * rights to redistribute these changes. 62 * rights to redistribute these changes.
63 */ 63 */
64 64
65#if defined(PDSIM) 65#if defined(PDSIM)
66 66
67#include "pdsim.h" 67#include "pdsim.h"
68 68
69#else /* defined(PDSIM) */ 69#else /* defined(PDSIM) */
70 70
71#include <sys/cdefs.h> 71#include <sys/cdefs.h>
72__KERNEL_RCSID(0, "$NetBSD: uvm_pdpolicy_clock.c,v 1.16 2012/01/28 00:00:06 rmind Exp $"); 72__KERNEL_RCSID(0, "$NetBSD: uvm_pdpolicy_clock.c,v 1.17 2012/01/30 17:21:52 para Exp $");
73 73
74#include <sys/param.h> 74#include <sys/param.h>
75#include <sys/proc.h> 75#include <sys/proc.h>
76#include <sys/systm.h> 76#include <sys/systm.h>
77#include <sys/kernel.h> 77#include <sys/kernel.h>
78 78
79#include <uvm/uvm.h> 79#include <uvm/uvm.h>
80#include <uvm/uvm_pdpolicy.h> 80#include <uvm/uvm_pdpolicy.h>
81#include <uvm/uvm_pdpolicy_impl.h> 81#include <uvm/uvm_pdpolicy_impl.h>
82 82
83#endif /* defined(PDSIM) */ 83#endif /* defined(PDSIM) */
84 84
85#define PQ_INACTIVE PQ_PRIVATE1 /* page is in inactive list */ 85#define PQ_INACTIVE PQ_PRIVATE1 /* page is in inactive list */
86#define PQ_ACTIVE PQ_PRIVATE2 /* page is in active list */ 86#define PQ_ACTIVE PQ_PRIVATE2 /* page is in active list */
87 87
88#if !defined(CLOCK_INACTIVEPCT) 88#if !defined(CLOCK_INACTIVEPCT)
89#define CLOCK_INACTIVEPCT 33 89#define CLOCK_INACTIVEPCT 33
90#endif /* !defined(CLOCK_INACTIVEPCT) */ 90#endif /* !defined(CLOCK_INACTIVEPCT) */
91 91
92struct uvmpdpol_globalstate { 92struct uvmpdpol_globalstate {
93 struct pglist s_activeq; /* allocated pages, in use */ 93 struct pglist s_activeq; /* allocated pages, in use */
94 struct pglist s_inactiveq; /* pages between the clock hands */ 94 struct pglist s_inactiveq; /* pages between the clock hands */
95 int s_active; 95 int s_active;
96 int s_inactive; 96 int s_inactive;
97 int s_inactarg; 97 int s_inactarg;
98 struct uvm_pctparam s_anonmin; 98 struct uvm_pctparam s_anonmin;
99 struct uvm_pctparam s_filemin; 99 struct uvm_pctparam s_filemin;
100 struct uvm_pctparam s_execmin; 100 struct uvm_pctparam s_execmin;
101 struct uvm_pctparam s_anonmax; 101 struct uvm_pctparam s_anonmax;
102 struct uvm_pctparam s_filemax; 102 struct uvm_pctparam s_filemax;
103 struct uvm_pctparam s_execmax; 103 struct uvm_pctparam s_execmax;
104 struct uvm_pctparam s_inactivepct; 104 struct uvm_pctparam s_inactivepct;
105}; 105};
106 106
107struct uvmpdpol_scanstate { 107struct uvmpdpol_scanstate {
108 bool ss_first; 108 bool ss_first;
109 bool ss_anonreact, ss_filereact, ss_execreact; 109 bool ss_anonreact, ss_filereact, ss_execreact;
110 struct vm_page *ss_nextpg; 110 struct vm_page *ss_nextpg;
111}; 111};
112 112
113static struct uvmpdpol_globalstate pdpol_state; 113static struct uvmpdpol_globalstate pdpol_state;
114static struct uvmpdpol_scanstate pdpol_scanstate; 114static struct uvmpdpol_scanstate pdpol_scanstate;
115 115
116PDPOL_EVCNT_DEFINE(reactexec) 116PDPOL_EVCNT_DEFINE(reactexec)
117PDPOL_EVCNT_DEFINE(reactfile) 117PDPOL_EVCNT_DEFINE(reactfile)
118PDPOL_EVCNT_DEFINE(reactanon) 118PDPOL_EVCNT_DEFINE(reactanon)
119 119
120static void 120static void
121clock_tune(void) 121clock_tune(void)
122{ 122{
123 struct uvmpdpol_globalstate *s = &pdpol_state; 123 struct uvmpdpol_globalstate *s = &pdpol_state;
124 124
125 s->s_inactarg = UVM_PCTPARAM_APPLY(&s->s_inactivepct, 125 s->s_inactarg = UVM_PCTPARAM_APPLY(&s->s_inactivepct,
126 s->s_active + s->s_inactive); 126 s->s_active + s->s_inactive);
127 if (s->s_inactarg <= uvmexp.freetarg) { 127 if (s->s_inactarg <= uvmexp.freetarg) {
128 s->s_inactarg = uvmexp.freetarg + 1; 128 s->s_inactarg = uvmexp.freetarg + 1;
129 } 129 }
130} 130}
131 131
132void 132void
133uvmpdpol_scaninit(void) 133uvmpdpol_scaninit(void)
134{ 134{
135 struct uvmpdpol_globalstate *s = &pdpol_state; 135 struct uvmpdpol_globalstate *s = &pdpol_state;
136 struct uvmpdpol_scanstate *ss = &pdpol_scanstate; 136 struct uvmpdpol_scanstate *ss = &pdpol_scanstate;
137 int t; 137 int t;
138 bool anonunder, fileunder, execunder; 138 bool anonunder, fileunder, execunder;
139 bool anonover, fileover, execover; 139 bool anonover, fileover, execover;
140 bool anonreact, filereact, execreact; 140 bool anonreact, filereact, execreact;
141 141
142 /* 142 /*
143 * decide which types of pages we want to reactivate instead of freeing 143 * decide which types of pages we want to reactivate instead of freeing
144 * to keep usage within the minimum and maximum usage limits. 144 * to keep usage within the minimum and maximum usage limits.
145 */ 145 */
146 146
147 t = s->s_active + s->s_inactive + uvmexp.free; 147 t = s->s_active + s->s_inactive + uvmexp.free;
148 anonunder = uvmexp.anonpages <= UVM_PCTPARAM_APPLY(&s->s_anonmin, t); 148 anonunder = uvmexp.anonpages <= UVM_PCTPARAM_APPLY(&s->s_anonmin, t);
149 fileunder = uvmexp.filepages <= UVM_PCTPARAM_APPLY(&s->s_filemin, t); 149 fileunder = uvmexp.filepages <= UVM_PCTPARAM_APPLY(&s->s_filemin, t);
150 execunder = uvmexp.execpages <= UVM_PCTPARAM_APPLY(&s->s_execmin, t); 150 execunder = uvmexp.execpages <= UVM_PCTPARAM_APPLY(&s->s_execmin, t);
151 anonover = uvmexp.anonpages > UVM_PCTPARAM_APPLY(&s->s_anonmax, t); 151 anonover = uvmexp.anonpages > UVM_PCTPARAM_APPLY(&s->s_anonmax, t);
152 fileover = uvmexp.filepages > UVM_PCTPARAM_APPLY(&s->s_filemax, t); 152 fileover = uvmexp.filepages > UVM_PCTPARAM_APPLY(&s->s_filemax, t);
153 execover = uvmexp.execpages > UVM_PCTPARAM_APPLY(&s->s_execmax, t); 153 execover = uvmexp.execpages > UVM_PCTPARAM_APPLY(&s->s_execmax, t);
154 anonreact = anonunder || (!anonover && (fileover || execover)); 154 anonreact = anonunder || (!anonover && (fileover || execover));
155 filereact = fileunder || (!fileover && (anonover || execover)); 155 filereact = fileunder || (!fileover && (anonover || execover));
156 execreact = execunder || (!execover && (anonover || fileover)); 156 execreact = execunder || (!execover && (anonover || fileover));
157 if (filereact && execreact && (anonreact || uvm_swapisfull())) { 157 if (filereact && execreact && (anonreact || uvm_swapisfull())) {
158 anonreact = filereact = execreact = false; 158 anonreact = filereact = execreact = false;
159 } 159 }
160 ss->ss_anonreact = anonreact; 160 ss->ss_anonreact = anonreact;
161 ss->ss_filereact = filereact; 161 ss->ss_filereact = filereact;
162 ss->ss_execreact = execreact; 162 ss->ss_execreact = execreact;
163 163
164 ss->ss_first = true; 164 ss->ss_first = true;
165} 165}
166 166
167struct vm_page * 167struct vm_page *
168uvmpdpol_selectvictim(void) 168uvmpdpol_selectvictim(void)
169{ 169{
170 struct uvmpdpol_scanstate *ss = &pdpol_scanstate; 170 struct uvmpdpol_scanstate *ss = &pdpol_scanstate;
171 struct vm_page *pg; 171 struct vm_page *pg;
172 kmutex_t *lock; 172 kmutex_t *lock;
173 173
174 KASSERT(mutex_owned(&uvm_pageqlock)); 174 KASSERT(mutex_owned(&uvm_pageqlock));
175 175
176 while (/* CONSTCOND */ 1) { 176 while (/* CONSTCOND */ 1) {
177 struct vm_anon *anon; 177 struct vm_anon *anon;
178 struct uvm_object *uobj; 178 struct uvm_object *uobj;
179 179
180 if (ss->ss_first) { 180 if (ss->ss_first) {
181 pg = TAILQ_FIRST(&pdpol_state.s_inactiveq); 181 pg = TAILQ_FIRST(&pdpol_state.s_inactiveq);
182 ss->ss_first = false; 182 ss->ss_first = false;
183 } else { 183 } else {
184 pg = ss->ss_nextpg; 184 pg = ss->ss_nextpg;
185 if (pg != NULL && (pg->pqflags & PQ_INACTIVE) == 0) { 185 if (pg != NULL && (pg->pqflags & PQ_INACTIVE) == 0) {
186 pg = TAILQ_FIRST(&pdpol_state.s_inactiveq); 186 pg = TAILQ_FIRST(&pdpol_state.s_inactiveq);
187 } 187 }
188 } 188 }
189 if (pg == NULL) { 189 if (pg == NULL) {
190 break; 190 break;
191 } 191 }
192 ss->ss_nextpg = TAILQ_NEXT(pg, pageq.queue); 192 ss->ss_nextpg = TAILQ_NEXT(pg, pageq.queue);
193 193
194 uvmexp.pdscans++; 194 uvmexp.pdscans++;
195 195
196 /* 196 /*
197 * move referenced pages back to active queue and 197 * move referenced pages back to active queue and
198 * skip to next page. 198 * skip to next page.
199 */ 199 */
200 200
201 lock = uvmpd_trylockowner(pg); 201 lock = uvmpd_trylockowner(pg);
202 if (lock != NULL) { 202 if (lock != NULL) {
203 if (pmap_is_referenced(pg)) { 203 if (pmap_is_referenced(pg)) {
204 uvmpdpol_pageactivate(pg); 204 uvmpdpol_pageactivate(pg);
205 uvmexp.pdreact++; 205 uvmexp.pdreact++;
206 mutex_exit(lock); 206 mutex_exit(lock);
207 continue; 207 continue;
208 } 208 }
209 mutex_exit(lock); 209 mutex_exit(lock);
210 } 210 }
211 211
212 anon = pg->uanon; 212 anon = pg->uanon;
213 uobj = pg->uobject; 213 uobj = pg->uobject;
214 214
215 /* 215 /*
216 * enforce the minimum thresholds on different 216 * enforce the minimum thresholds on different
217 * types of memory usage. if reusing the current 217 * types of memory usage. if reusing the current
218 * page would reduce that type of usage below its 218 * page would reduce that type of usage below its
219 * minimum, reactivate the page instead and move 219 * minimum, reactivate the page instead and move
220 * on to the next page. 220 * on to the next page.
221 */ 221 */
222 222
223 if (uobj && UVM_OBJ_IS_VTEXT(uobj) && ss->ss_execreact) { 223 if (uobj && UVM_OBJ_IS_VTEXT(uobj) && ss->ss_execreact) {
224 uvmpdpol_pageactivate(pg); 224 uvmpdpol_pageactivate(pg);
225 PDPOL_EVCNT_INCR(reactexec); 225 PDPOL_EVCNT_INCR(reactexec);
226 continue; 226 continue;
227 } 227 }
228 if (uobj && UVM_OBJ_IS_VNODE(uobj) && 228 if (uobj && UVM_OBJ_IS_VNODE(uobj) &&
229 !UVM_OBJ_IS_VTEXT(uobj) && ss->ss_filereact) { 229 !UVM_OBJ_IS_VTEXT(uobj) && ss->ss_filereact) {
230 uvmpdpol_pageactivate(pg); 230 uvmpdpol_pageactivate(pg);
231 PDPOL_EVCNT_INCR(reactfile); 231 PDPOL_EVCNT_INCR(reactfile);
232 continue; 232 continue;
233 } 233 }
234 if ((anon || UVM_OBJ_IS_AOBJ(uobj)) && ss->ss_anonreact) { 234 if ((anon || UVM_OBJ_IS_AOBJ(uobj)) && ss->ss_anonreact) {
235 uvmpdpol_pageactivate(pg); 235 uvmpdpol_pageactivate(pg);
236 PDPOL_EVCNT_INCR(reactanon); 236 PDPOL_EVCNT_INCR(reactanon);
237 continue; 237 continue;
238 } 238 }
239 239
240 break; 240 break;
241 } 241 }
242 242
243 return pg; 243 return pg;
244} 244}
245 245
246void 246void
247uvmpdpol_balancequeue(int swap_shortage) 247uvmpdpol_balancequeue(int swap_shortage)
248{ 248{
249 int inactive_shortage; 249 int inactive_shortage;
250 struct vm_page *p, *nextpg; 250 struct vm_page *p, *nextpg;
251 kmutex_t *lock; 251 kmutex_t *lock;
252 252
253 /* 253 /*
254 * we have done the scan to get free pages. now we work on meeting 254 * we have done the scan to get free pages. now we work on meeting
255 * our inactive target. 255 * our inactive target.
256 */ 256 */
257 257
258 inactive_shortage = pdpol_state.s_inactarg - pdpol_state.s_inactive; 258 inactive_shortage = pdpol_state.s_inactarg - pdpol_state.s_inactive;
259 for (p = TAILQ_FIRST(&pdpol_state.s_activeq); 259 for (p = TAILQ_FIRST(&pdpol_state.s_activeq);
260 p != NULL && (inactive_shortage > 0 || swap_shortage > 0); 260 p != NULL && (inactive_shortage > 0 || swap_shortage > 0);
261 p = nextpg) { 261 p = nextpg) {
262 nextpg = TAILQ_NEXT(p, pageq.queue); 262 nextpg = TAILQ_NEXT(p, pageq.queue);
263 263
264 /* 264 /*
265 * if there's a shortage of swap slots, try to free it. 265 * if there's a shortage of swap slots, try to free it.
266 */ 266 */
267 267
268 if (swap_shortage > 0 && (p->pqflags & PQ_SWAPBACKED) != 0) { 268 if (swap_shortage > 0 && (p->pqflags & PQ_SWAPBACKED) != 0) {
269 if (uvmpd_trydropswap(p)) { 269 if (uvmpd_trydropswap(p)) {
270 swap_shortage--; 270 swap_shortage--;
271 } 271 }
272 } 272 }
273 273
274 /* 274 /*
275 * if there's a shortage of inactive pages, deactivate. 275 * if there's a shortage of inactive pages, deactivate.
276 */ 276 */
277 277
278 if (inactive_shortage <= 0) { 278 if (inactive_shortage <= 0) {
279 continue; 279 continue;
280 } 280 }
281 281
282 /* no need to check wire_count as pg is "active" */ 282 /* no need to check wire_count as pg is "active" */
283 lock = uvmpd_trylockowner(p); 283 lock = uvmpd_trylockowner(p);
284 if (lock != NULL) { 284 if (lock != NULL) {
285 uvmpdpol_pagedeactivate(p); 285 uvmpdpol_pagedeactivate(p);
286 uvmexp.pddeact++; 286 uvmexp.pddeact++;
287 inactive_shortage--; 287 inactive_shortage--;
288 mutex_exit(lock); 288 mutex_exit(lock);
289 } 289 }
290 } 290 }
291} 291}
292 292
293void 293void
294uvmpdpol_pagedeactivate(struct vm_page *pg) 294uvmpdpol_pagedeactivate(struct vm_page *pg)
295{ 295{
296 296
297 KASSERT(uvm_page_locked_p(pg)); 297 KASSERT(uvm_page_locked_p(pg));
298 KASSERT(mutex_owned(&uvm_pageqlock)); 298 KASSERT(mutex_owned(&uvm_pageqlock));
299 299
300 if (pg->pqflags & PQ_ACTIVE) { 300 if (pg->pqflags & PQ_ACTIVE) {
301 TAILQ_REMOVE(&pdpol_state.s_activeq, pg, pageq.queue); 301 TAILQ_REMOVE(&pdpol_state.s_activeq, pg, pageq.queue);
302 pg->pqflags &= ~PQ_ACTIVE; 302 pg->pqflags &= ~PQ_ACTIVE;
303 KASSERT(pdpol_state.s_active > 0); 303 KASSERT(pdpol_state.s_active > 0);
304 pdpol_state.s_active--; 304 pdpol_state.s_active--;
305 } 305 }
306 if ((pg->pqflags & PQ_INACTIVE) == 0) { 306 if ((pg->pqflags & PQ_INACTIVE) == 0) {
307 KASSERT(pg->wire_count == 0); 307 KASSERT(pg->wire_count == 0);
308 pmap_clear_reference(pg); 308 pmap_clear_reference(pg);
309 TAILQ_INSERT_TAIL(&pdpol_state.s_inactiveq, pg, pageq.queue); 309 TAILQ_INSERT_TAIL(&pdpol_state.s_inactiveq, pg, pageq.queue);
310 pg->pqflags |= PQ_INACTIVE; 310 pg->pqflags |= PQ_INACTIVE;
311 pdpol_state.s_inactive++; 311 pdpol_state.s_inactive++;
312 } 312 }
313} 313}
314 314
315void 315void
316uvmpdpol_pageactivate(struct vm_page *pg) 316uvmpdpol_pageactivate(struct vm_page *pg)
317{ 317{
318 318
319 uvmpdpol_pagedequeue(pg); 319 uvmpdpol_pagedequeue(pg);
320 TAILQ_INSERT_TAIL(&pdpol_state.s_activeq, pg, pageq.queue); 320 TAILQ_INSERT_TAIL(&pdpol_state.s_activeq, pg, pageq.queue);
321 pg->pqflags |= PQ_ACTIVE; 321 pg->pqflags |= PQ_ACTIVE;
322 pdpol_state.s_active++; 322 pdpol_state.s_active++;
323} 323}
324 324
325void 325void
326uvmpdpol_pagedequeue(struct vm_page *pg) 326uvmpdpol_pagedequeue(struct vm_page *pg)
327{ 327{
328 328
329 if (pg->pqflags & PQ_ACTIVE) { 329 if (pg->pqflags & PQ_ACTIVE) {
330 KASSERT(mutex_owned(&uvm_pageqlock)); 330 KASSERT(mutex_owned(&uvm_pageqlock));
331 TAILQ_REMOVE(&pdpol_state.s_activeq, pg, pageq.queue); 331 TAILQ_REMOVE(&pdpol_state.s_activeq, pg, pageq.queue);
332 pg->pqflags &= ~PQ_ACTIVE; 332 pg->pqflags &= ~PQ_ACTIVE;
333 KASSERT(pdpol_state.s_active > 0); 333 KASSERT(pdpol_state.s_active > 0);
334 pdpol_state.s_active--; 334 pdpol_state.s_active--;
335 } else if (pg->pqflags & PQ_INACTIVE) { 335 } else if (pg->pqflags & PQ_INACTIVE) {
336 KASSERT(mutex_owned(&uvm_pageqlock)); 336 KASSERT(mutex_owned(&uvm_pageqlock));
337 TAILQ_REMOVE(&pdpol_state.s_inactiveq, pg, pageq.queue); 337 TAILQ_REMOVE(&pdpol_state.s_inactiveq, pg, pageq.queue);
338 pg->pqflags &= ~PQ_INACTIVE; 338 pg->pqflags &= ~PQ_INACTIVE;
339 KASSERT(pdpol_state.s_inactive > 0); 339 KASSERT(pdpol_state.s_inactive > 0);
340 pdpol_state.s_inactive--; 340 pdpol_state.s_inactive--;
341 } 341 }
342} 342}
343 343
344void 344void
345uvmpdpol_pageenqueue(struct vm_page *pg) 345uvmpdpol_pageenqueue(struct vm_page *pg)
346{ 346{
347 347
348 uvmpdpol_pageactivate(pg); 348 uvmpdpol_pageactivate(pg);
349} 349}
350 350
351void 351void
352uvmpdpol_anfree(struct vm_anon *an) 352uvmpdpol_anfree(struct vm_anon *an)
353{ 353{
354} 354}
355 355
356bool 356bool
357uvmpdpol_pageisqueued_p(struct vm_page *pg) 357uvmpdpol_pageisqueued_p(struct vm_page *pg)
358{ 358{
359 359
360 return (pg->pqflags & (PQ_ACTIVE | PQ_INACTIVE)) != 0; 360 return (pg->pqflags & (PQ_ACTIVE | PQ_INACTIVE)) != 0;
361} 361}
362 362
363void 363void
364uvmpdpol_estimatepageable(int *active, int *inactive) 364uvmpdpol_estimatepageable(int *active, int *inactive)
365{ 365{
366 366
367 if (active) { 367 if (active) {
368 *active = pdpol_state.s_active; 368 *active = pdpol_state.s_active;
369 } 369 }
370 if (inactive) { 370 if (inactive) {
371 *inactive = pdpol_state.s_inactive; 371 *inactive = pdpol_state.s_inactive;
372 } 372 }
373} 373}
374 374
375#if !defined(PDSIM) 375#if !defined(PDSIM)
376static int 376static int
377min_check(struct uvm_pctparam *pct, int t) 377min_check(struct uvm_pctparam *pct, int t)
378{ 378{
379 struct uvmpdpol_globalstate *s = &pdpol_state; 379 struct uvmpdpol_globalstate *s = &pdpol_state;
380 int total = t; 380 int total = t;
381 381
382 if (pct != &s->s_anonmin) { 382 if (pct != &s->s_anonmin) {
383 total += uvm_pctparam_get(&s->s_anonmin); 383 total += uvm_pctparam_get(&s->s_anonmin);
384 } 384 }
385 if (pct != &s->s_filemin) { 385 if (pct != &s->s_filemin) {
386 total += uvm_pctparam_get(&s->s_filemin); 386 total += uvm_pctparam_get(&s->s_filemin);
387 } 387 }
388 if (pct != &s->s_execmin) { 388 if (pct != &s->s_execmin) {
389 total += uvm_pctparam_get(&s->s_execmin); 389 total += uvm_pctparam_get(&s->s_execmin);
390 } 390 }
391 if (total > 95) { 391 if (total > 95) {
392 return EINVAL; 392 return EINVAL;
393 } 393 }
394 return 0; 394 return 0;
395} 395}
396#endif /* !defined(PDSIM) */ 396#endif /* !defined(PDSIM) */
397 397
398void 398void
399uvmpdpol_init(void) 399uvmpdpol_init(void)
400{ 400{
401 struct uvmpdpol_globalstate *s = &pdpol_state; 401 struct uvmpdpol_globalstate *s = &pdpol_state;
402 402
403 TAILQ_INIT(&s->s_activeq); 403 TAILQ_INIT(&s->s_activeq);
404 TAILQ_INIT(&s->s_inactiveq); 404 TAILQ_INIT(&s->s_inactiveq);
405 uvm_pctparam_init(&s->s_inactivepct, CLOCK_INACTIVEPCT, NULL); 405 uvm_pctparam_init(&s->s_inactivepct, CLOCK_INACTIVEPCT, NULL);
406 uvm_pctparam_init(&s->s_anonmin, 10, min_check); 406 uvm_pctparam_init(&s->s_anonmin, 10, min_check);
407 uvm_pctparam_init(&s->s_filemin, 10, min_check); 407 uvm_pctparam_init(&s->s_filemin, 10, min_check);
408 uvm_pctparam_init(&s->s_execmin, 5, min_check); 408 uvm_pctparam_init(&s->s_execmin, 5, min_check);
409 uvm_pctparam_init(&s->s_anonmax, 80, NULL); 409 uvm_pctparam_init(&s->s_anonmax, 80, NULL);
410 uvm_pctparam_init(&s->s_filemax, 50, NULL); 410 uvm_pctparam_init(&s->s_filemax, 50, NULL);
411 uvm_pctparam_init(&s->s_execmax, 30, NULL); 411 uvm_pctparam_init(&s->s_execmax, 30, NULL);
412} 412}
413 413
414void 414void
415uvmpdpol_reinit(void) 415uvmpdpol_reinit(void)
416{ 416{
417} 417}
418 418
419bool 419bool
420uvmpdpol_needsscan_p(void) 420uvmpdpol_needsscan_p(void)
421{ 421{
422 vmem_size_t kva_size, kva_free; 
423 422
424 kva_size = vmem_size(kmem_arena, VMEM_FREE | VMEM_ALLOC); 423 return pdpol_state.s_inactive < pdpol_state.s_inactarg;
425 kva_free = vmem_size(kmem_arena, VMEM_FREE); 
426 
427 if (kva_free < (kva_size / 10)) { 
428 return true; 
429 } 
430 
431 if (pdpol_state.s_inactive < pdpol_state.s_inactarg) { 
432 return true; 
433 } 
434 if (pdpol_state.s_inactive < pdpol_state.s_inactarg) { 
435 return true; 
436 } 
437 return false; 
438} 424}
439 425
440void 426void
441uvmpdpol_tune(void) 427uvmpdpol_tune(void)
442{ 428{
443 429
444 clock_tune(); 430 clock_tune();
445} 431}
446 432
447#if !defined(PDSIM) 433#if !defined(PDSIM)
448 434
449#include <sys/sysctl.h> /* XXX SYSCTL_DESCR */ 435#include <sys/sysctl.h> /* XXX SYSCTL_DESCR */
450 436
451void 437void
452uvmpdpol_sysctlsetup(void) 438uvmpdpol_sysctlsetup(void)
453{ 439{
454 struct uvmpdpol_globalstate *s = &pdpol_state; 440 struct uvmpdpol_globalstate *s = &pdpol_state;
455 441
456 uvm_pctparam_createsysctlnode(&s->s_anonmin, "anonmin", 442 uvm_pctparam_createsysctlnode(&s->s_anonmin, "anonmin",
457 SYSCTL_DESCR("Percentage of physical memory reserved " 443 SYSCTL_DESCR("Percentage of physical memory reserved "
458 "for anonymous application data")); 444 "for anonymous application data"));
459 uvm_pctparam_createsysctlnode(&s->s_filemin, "filemin", 445 uvm_pctparam_createsysctlnode(&s->s_filemin, "filemin",
460 SYSCTL_DESCR("Percentage of physical memory reserved " 446 SYSCTL_DESCR("Percentage of physical memory reserved "
461 "for cached file data")); 447 "for cached file data"));
462 uvm_pctparam_createsysctlnode(&s->s_execmin, "execmin", 448 uvm_pctparam_createsysctlnode(&s->s_execmin, "execmin",
463 SYSCTL_DESCR("Percentage of physical memory reserved " 449 SYSCTL_DESCR("Percentage of physical memory reserved "
464 "for cached executable data")); 450 "for cached executable data"));
465 451
466 uvm_pctparam_createsysctlnode(&s->s_anonmax, "anonmax", 452 uvm_pctparam_createsysctlnode(&s->s_anonmax, "anonmax",
467 SYSCTL_DESCR("Percentage of physical memory which will " 453 SYSCTL_DESCR("Percentage of physical memory which will "
468 "be reclaimed from other usage for " 454 "be reclaimed from other usage for "
469 "anonymous application data")); 455 "anonymous application data"));
470 uvm_pctparam_createsysctlnode(&s->s_filemax, "filemax", 456 uvm_pctparam_createsysctlnode(&s->s_filemax, "filemax",
471 SYSCTL_DESCR("Percentage of physical memory which will " 457 SYSCTL_DESCR("Percentage of physical memory which will "
472 "be reclaimed from other usage for cached " 458 "be reclaimed from other usage for cached "
473 "file data")); 459 "file data"));
474 uvm_pctparam_createsysctlnode(&s->s_execmax, "execmax", 460 uvm_pctparam_createsysctlnode(&s->s_execmax, "execmax",
475 SYSCTL_DESCR("Percentage of physical memory which will " 461 SYSCTL_DESCR("Percentage of physical memory which will "
476 "be reclaimed from other usage for cached " 462 "be reclaimed from other usage for cached "
477 "executable data")); 463 "executable data"));
478 464
479 uvm_pctparam_createsysctlnode(&s->s_inactivepct, "inactivepct", 465 uvm_pctparam_createsysctlnode(&s->s_inactivepct, "inactivepct",
480 SYSCTL_DESCR("Percentage of inactive queue of " 466 SYSCTL_DESCR("Percentage of inactive queue of "
481 "the entire (active + inactive) queue")); 467 "the entire (active + inactive) queue"));
482} 468}
483 469
484#endif /* !defined(PDSIM) */ 470#endif /* !defined(PDSIM) */
485 471
486#if defined(PDSIM) 472#if defined(PDSIM)
487void 473void
488pdsim_dump(const char *id) 474pdsim_dump(const char *id)
489{ 475{
490#if defined(DEBUG) 476#if defined(DEBUG)
491 /* XXX */ 477 /* XXX */
492#endif /* defined(DEBUG) */ 478#endif /* defined(DEBUG) */
493} 479}
494#endif /* defined(PDSIM) */ 480#endif /* defined(PDSIM) */