Put in proper address information for Poul-Henning Kamp.
[unix-history] / sys / vm / vm_pageout.c
CommitLineData
15637ed4
RG
1/*
2 * Copyright (c) 1991 Regents of the University of California.
3 * All rights reserved.
55768178
DG
4 * Copyright (c) 1994 John S. Dyson
5 * All rights reserved.
6 * Copyright (c) 1994 David Greenman
7 * All rights reserved.
15637ed4
RG
8 *
9 * This code is derived from software contributed to Berkeley by
10 * The Mach Operating System project at Carnegie-Mellon University.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in the
19 * documentation and/or other materials provided with the distribution.
20 * 3. All advertising materials mentioning features or use of this software
21 * must display the following acknowledgement:
22 * This product includes software developed by the University of
23 * California, Berkeley and its contributors.
24 * 4. Neither the name of the University nor the names of its contributors
25 * may be used to endorse or promote products derived from this software
26 * without specific prior written permission.
27 *
28 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
29 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
31 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
32 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
36 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
37 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
38 * SUCH DAMAGE.
39 *
55768178
DG
40 * @(#)vm_pageout.c 7.4 (Berkeley) 5/7/91
41 *
42 *
15637ed4
RG
43 * Copyright (c) 1987, 1990 Carnegie-Mellon University.
44 * All rights reserved.
45 *
46 * Authors: Avadis Tevanian, Jr., Michael Wayne Young
47 *
48 * Permission to use, copy, modify and distribute this software and
49 * its documentation is hereby granted, provided that both the copyright
50 * notice and this permission notice appear in all copies of the
51 * software, derivative works or modified versions, and any portions
52 * thereof, and that both notices appear in supporting documentation.
53 *
54 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
55 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
56 * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
57 *
58 * Carnegie Mellon requests users of this software to return to
59 *
60 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
61 * School of Computer Science
62 * Carnegie Mellon University
63 * Pittsburgh PA 15213-3890
64 *
65 * any improvements or extensions that they make and grant Carnegie the
66 * rights to redistribute these changes.
55768178 67 *
b7ae9810 68 * $Id: vm_pageout.c,v 1.12 1994/01/31 04:21:28 davidg Exp $
15637ed4
RG
69 */
70
71/*
72 * The proverbial page-out daemon.
73 */
74
75#include "param.h"
76
77#include "vm.h"
78#include "vm_page.h"
79#include "vm_pageout.h"
55768178
DG
80#include "malloc.h"
81#include "proc.h"
82#include "resource.h"
83#include "resourcevar.h"
15637ed4
RG
84#include "vmmeter.h"
85
55768178 86extern vm_map_t kmem_map;
15637ed4
RG
87int vm_pages_needed; /* Event on which pageout daemon sleeps */
88int vm_pageout_free_min = 0; /* Stop pageout to wait for pagers at this free level */
89
55768178
DG
90int vm_pageout_pages_needed = 0; /* flag saying that the pageout daemon needs pages */
91int vm_page_pagesfreed;
92
93extern int npendingio;
94extern int hz;
95int vm_pageout_proc_limit;
96extern int nswiodone;
97
98#define MAXREF 32767
a200ca2b
DG
99#define DEACT_MAX (DEACT_START * 4)
100#define MINSCAN 512 /* minimum number of pages to scan in active queue */
101 /* set the "clock" hands to be (MINSCAN * 4096) Bytes */
102static int minscan;
103void vm_pageout_deact_bump(vm_page_t m) ;
104
55768178
DG
105
106/*
107 * vm_pageout_clean:
108 * cleans a vm_page
109 */
110int
111vm_pageout_clean(m, wait)
112 register vm_page_t m;
113 int wait;
114{
115 /*
116 * Clean the page and remove it from the
117 * laundry.
118 *
119 * We set the busy bit to cause
120 * potential page faults on this page to
121 * block.
122 *
123 * And we set pageout-in-progress to keep
124 * the object from disappearing during
125 * pageout. This guarantees that the
126 * page won't move from the inactive
127 * queue. (However, any other page on
128 * the inactive queue may move!)
129 */
130
131 register vm_object_t object;
132 register vm_pager_t pager;
133 int pageout_status;
134
135 object = m->object;
136 if (!object) {
137 printf("pager: object missing\n");
138 return 0;
139 }
140
141 /*
142 * Try to collapse the object before
143 * making a pager for it. We must
144 * unlock the page queues first.
145 * We try to defer the creation of a pager
146 * until all shadows are not paging. This
147 * allows vm_object_collapse to work better and
148 * helps control swap space size.
149 * (J. Dyson 11 Nov 93)
150 */
151
152 if (!object->pager &&
153 vm_page_free_count < vm_pageout_free_min)
154 return 0;
155
a200ca2b 156collapseagain:
55768178
DG
157 if (!object->pager &&
158 object->shadow &&
159 object->shadow->paging_in_progress)
160 return 0;
161
162 if (object->shadow) {
163 vm_offset_t offset = m->offset;
164 vm_object_collapse(object);
165 if (!vm_page_lookup(object, offset))
166 return 0;
167 }
168
169waitagain:
170 if (!wait && (m->flags & PG_BUSY)) {
171 return 0;
172 } else if (m->flags & PG_BUSY) {
173 int s = splhigh();
174 m->flags |= PG_WANTED;
175 tsleep((caddr_t)m, PVM, "clnslp", 0);
176 splx(s);
177 goto waitagain;
178 }
179
180 m->flags |= PG_BUSY;
181
182 pmap_page_protect(VM_PAGE_TO_PHYS(m), VM_PROT_READ);
55768178
DG
183
184 vm_stat.pageouts++;
185
186 object->paging_in_progress++;
187
188 /*
189 * If there is no pager for the page,
190 * use the default pager. If there's
191 * no place to put the page at the
192 * moment, leave it in the laundry and
193 * hope that there will be paging space
194 * later.
195 */
196
197 if ((pager = object->pager) == NULL) {
198 pager = vm_pager_allocate(PG_DFLT, (caddr_t)0,
199 object->size, VM_PROT_ALL, 0);
200 if (pager != NULL) {
201 vm_object_setpager(object, pager, 0, FALSE);
202 }
203 }
204 if ((pager && pager->pg_type == PG_SWAP) ||
205 vm_page_free_count >= vm_pageout_free_min) {
206 pageout_status = pager ?
207 vm_pager_put(pager, m, (((object == kernel_object) || wait) ? TRUE: FALSE)) :
208 VM_PAGER_FAIL;
209 } else
210 pageout_status = VM_PAGER_FAIL;
211
212 switch (pageout_status) {
213 case VM_PAGER_OK:
214 m->flags &= ~PG_LAUNDRY;
215 break;
216 case VM_PAGER_PEND:
217 m->flags &= ~PG_LAUNDRY;
218 break;
219 case VM_PAGER_BAD:
220 /*
221 * Page outside of range of object.
222 * Right now we essentially lose the
223 * changes by pretending it worked.
224 */
225 m->flags &= ~PG_LAUNDRY;
226 m->flags |= PG_CLEAN;
227 pmap_clear_modify(VM_PAGE_TO_PHYS(m));
228 break;
229 case VM_PAGER_FAIL:
230 /*
231 * If page couldn't be paged out, then
232 * reactivate the page so it doesn't
233 * clog the inactive list. (We will
234 * try paging out it again later).
235 */
a200ca2b
DG
236 if ((m->flags & PG_ACTIVE) == 0)
237 vm_page_activate(m);
55768178
DG
238 break;
239 case VM_PAGER_TRYAGAIN:
240 break;
241 }
242
243
244 /*
245 * If the operation is still going, leave
246 * the page busy to block all other accesses.
247 * Also, leave the paging in progress
248 * indicator set so that we don't attempt an
249 * object collapse.
250 */
251 if (pageout_status != VM_PAGER_PEND) {
a200ca2b
DG
252 if ((m->flags & PG_ACTIVE) == 0 &&
253 pmap_is_referenced(VM_PAGE_TO_PHYS(m))) {
55768178
DG
254 vm_page_activate(m);
255 }
256 PAGE_WAKEUP(m);
257 if (--object->paging_in_progress == 0)
258 wakeup((caddr_t) object);
259 }
260 return (pageout_status == VM_PAGER_PEND ||
261 pageout_status == VM_PAGER_OK) ? 1 : 0;
262}
263
a200ca2b
DG
264int
265vm_fault_object_deactivate_pages(map, object, dummy)
266 vm_map_t map;
267 vm_object_t object;
268 int dummy;
269{
270 register vm_page_t p, next;
271 int rcount;
272 int s;
273 int dcount;
274 int count;
275
276 dcount = 0;
277 /*
278 * deactivate the pages in the objects shadow
279 */
280
281 if (object->shadow)
282 dcount += vm_fault_object_deactivate_pages(map, object->shadow, 0);
283
284 /*
285 * scan the objects memory queue and remove 20% of the active pages
286 */
287 rcount = object->resident_page_count;
288 count = rcount;
289 if (count == 0)
290 return dcount;
291#define MINOBJWRITE 10
292#define OBJDIVISOR 5
293 if (count > MINOBJWRITE) {
294 count = MINOBJWRITE + ((count - MINOBJWRITE) / OBJDIVISOR);
295 }
296 p = (vm_page_t) queue_first(&object->memq);
297 while ((rcount-- > 0) && !queue_end(&object->memq, (queue_entry_t) p) ) {
298 next = (vm_page_t) queue_next(&p->listq);
299 vm_page_lock_queues();
300 /*
301 * if a page is active, not wired and is in the processes pmap,
302 * then deactivate the page.
303 */
304 if ((p->flags & (PG_ACTIVE|PG_BUSY)) == PG_ACTIVE &&
305 p->wire_count == 0 &&
306 pmap_page_exists(vm_map_pmap(map), VM_PAGE_TO_PHYS(p))) {
307 if (!pmap_is_referenced(VM_PAGE_TO_PHYS(p))) {
308 vm_page_deactivate(p);
309 if ((p->flags & PG_CLEAN) == 0) {
310 vm_pageout_clean(p, 0);
311 }
312 ++dcount;
313 if (--count <= 0) {
314 vm_page_unlock_queues();
315 s = splbio();
316 while (object->paging_in_progress) {
317 tsleep((caddr_t) object,PVM,"vmfobw",0);
318 }
319 splx(s);
320 return dcount;
321 }
322 } else {
323 vm_pageout_deact_bump(p);
324 pmap_clear_reference(VM_PAGE_TO_PHYS(p));
325 queue_remove(&object->memq, p, vm_page_t, listq);
326 queue_enter(&object->memq, p, vm_page_t, listq);
327 queue_remove(&vm_page_queue_active, p, vm_page_t, pageq);
328 queue_enter(&vm_page_queue_active, p, vm_page_t, pageq);
329 }
330 /*
331 * if a page is inactive and has been modified, clean it now
332 */
333 } else if ((p->flags & (PG_INACTIVE|PG_BUSY)) == PG_INACTIVE) {
334 if ((p->flags & PG_CLEAN) &&
335 pmap_is_modified(VM_PAGE_TO_PHYS(p)))
336 p->flags &= ~PG_CLEAN;
337
338 if ((p->flags & PG_CLEAN) == 0)
339 vm_pageout_clean(p, 0);
340 }
341
342 vm_page_unlock_queues();
343 p = next;
344 }
345 s = splbio();
346 while (object->paging_in_progress) {
347 tsleep((caddr_t)object,PVM,"vmfobw",0);
348 }
349 splx(s);
350 return dcount;
351}
352
55768178
DG
353/*
354 * vm_pageout_object_deactivate_pages
355 *
356 * deactivate enough pages to satisfy the inactive target
357 * requirements or if vm_page_proc_limit is set, then
358 * deactivate all of the pages in the object and its
359 * shadows.
360 *
361 * The object and map must be locked.
362 */
363int
364vm_pageout_object_deactivate_pages(map, object, count)
365 vm_map_t map;
366 vm_object_t object;
367 int count;
368{
369 register vm_page_t p, next;
370 int rcount;
371 int s;
372 int dcount;
373
374 dcount = 0;
55768178
DG
375 if (count == 0)
376 count = 1;
377
a200ca2b 378 if (object->shadow) {
55768178 379 dcount += vm_pageout_object_deactivate_pages(map, object->shadow, count);
a200ca2b
DG
380 }
381
382 if (object->paging_in_progress)
383 return dcount;
55768178
DG
384
385 /*
386 * scan the objects entire memory queue
387 */
388 rcount = object->resident_page_count;
389 p = (vm_page_t) queue_first(&object->memq);
390 while ((rcount-- > 0) && !queue_end(&object->memq, (queue_entry_t) p) ) {
391 next = (vm_page_t) queue_next(&p->listq);
392 vm_page_lock_queues();
393 /*
394 * if a page is active, not wired and is in the processes pmap,
395 * then deactivate the page.
396 */
397 if ((p->flags & (PG_ACTIVE|PG_BUSY)) == PG_ACTIVE &&
398 p->wire_count == 0 &&
55768178
DG
399 pmap_page_exists(vm_map_pmap(map), VM_PAGE_TO_PHYS(p))) {
400 if (!pmap_is_referenced(VM_PAGE_TO_PHYS(p))) {
a200ca2b
DG
401 if (object->ref_count <= 1)
402 vm_page_deactivate(p);
403 else
404 vm_page_pageout_deactivate(p);
405 if (((p->flags & PG_INACTIVE)) &&
406 (p->flags & PG_CLEAN) == 0)
407 vm_pageout_clean(p, 0);
55768178
DG
408 /*
409 * see if we are done yet
410 */
411 if (p->flags & PG_INACTIVE) {
55768178
DG
412 --count;
413 ++dcount;
414 if (count <= 0 &&
415 vm_page_inactive_count > vm_page_inactive_target) {
416 vm_page_unlock_queues();
417 return dcount;
418 }
419 }
420
421 } else {
a200ca2b 422 vm_pageout_deact_bump(p);
55768178
DG
423 pmap_clear_reference(VM_PAGE_TO_PHYS(p));
424 queue_remove(&object->memq, p, vm_page_t, listq);
425 queue_enter(&object->memq, p, vm_page_t, listq);
426 queue_remove(&vm_page_queue_active, p, vm_page_t, pageq);
427 queue_enter(&vm_page_queue_active, p, vm_page_t, pageq);
428 }
a200ca2b
DG
429 /*
430 * if a page is inactive and has been modified, clean it now
431 */
432 } else if ((p->flags & (PG_INACTIVE|PG_BUSY)) == PG_INACTIVE) {
433 if ((p->flags & PG_CLEAN) &&
434 pmap_is_modified(VM_PAGE_TO_PHYS(p)))
435 p->flags &= ~PG_CLEAN;
436
437 if ((p->flags & PG_CLEAN) == 0)
438 vm_pageout_clean(p, 0);
55768178 439 }
a200ca2b 440
55768178
DG
441 vm_page_unlock_queues();
442 p = next;
443 }
444 return dcount;
445}
15637ed4 446
55768178
DG
447
448/*
449 * deactivate some number of pages in a map, try to do it fairly, but
450 * that is really hard to do.
451 */
452
453void
a200ca2b 454vm_pageout_map_deactivate_pages(map, entry, count, freeer)
55768178
DG
455 vm_map_t map;
456 vm_map_entry_t entry;
457 int *count;
a200ca2b 458 int (*freeer)(vm_map_t, vm_object_t, int);
55768178
DG
459{
460 vm_map_t tmpm;
461 vm_map_entry_t tmpe;
462 vm_object_t obj;
463 if (*count <= 0)
464 return;
465 vm_map_reference(map);
466 if (!lock_try_read(&map->lock)) {
467 vm_map_deallocate(map);
468 return;
469 }
470 if (entry == 0) {
471 tmpe = map->header.next;
472 while (tmpe != &map->header && *count > 0) {
a200ca2b 473 vm_pageout_map_deactivate_pages(map, tmpe, count, freeer);
55768178
DG
474 tmpe = tmpe->next;
475 };
476 } else if (entry->is_sub_map || entry->is_a_map) {
477 tmpm = entry->object.share_map;
478 tmpe = tmpm->header.next;
479 while (tmpe != &tmpm->header && *count > 0) {
a200ca2b 480 vm_pageout_map_deactivate_pages(tmpm, tmpe, count, freeer);
55768178
DG
481 tmpe = tmpe->next;
482 };
483 } else if (obj = entry->object.vm_object) {
a200ca2b 484 *count -= (*freeer)(map, obj, *count);
55768178
DG
485 }
486 lock_read_done(&map->lock);
487 vm_map_deallocate(map);
488 return;
489}
15637ed4 490
a200ca2b
DG
491void
492vm_fault_free_pages(p)
493 struct proc *p;
494{
495 int overage = 1;
496 vm_pageout_map_deactivate_pages(&p->p_vmspace->vm_map,
497 (vm_map_entry_t) 0, &overage, vm_fault_object_deactivate_pages);
498}
499
15637ed4
RG
500/*
501 * vm_pageout_scan does the dirty work for the pageout daemon.
502 */
4c45483e 503void
15637ed4
RG
504vm_pageout_scan()
505{
55768178
DG
506 vm_page_t m;
507 int page_shortage, maxscan, maxlaunder;
a200ca2b 508 int pages_freed, free, nproc, nbusy;
55768178
DG
509 vm_page_t next;
510 struct proc *p;
511 vm_object_t object;
512 int s;
513
15637ed4 514 /*
55768178 515 * deactivate objects with ref_counts == 0
15637ed4 516 */
55768178
DG
517 object = (vm_object_t) queue_first(&vm_object_list);
518 while (!queue_end(&vm_object_list, (queue_entry_t) object)) {
519 if (object->ref_count == 0)
520 vm_object_deactivate_pages(object);
521 object = (vm_object_t) queue_next(&object->object_list);
522 }
15637ed4 523
55768178
DG
524rerun:
525#if 1
15637ed4 526 /*
55768178
DG
527 * next scan the processes for exceeding their rlimits or if process
528 * is swapped out -- deactivate pages
15637ed4 529 */
55768178
DG
530
531rescanproc1a:
532 for (p = allproc; p != NULL; p = p->p_nxt)
533 p->p_flag &= ~SPAGEDAEMON;
534
535rescanproc1:
536 for (p = allproc; p != NULL; p = p->p_nxt) {
537 vm_offset_t size;
538 int overage;
539 vm_offset_t limit;
540
541 /*
542 * if this is a system process or if we have already
543 * looked at this process, skip it.
544 */
545 if (p->p_flag & (SSYS|SPAGEDAEMON|SWEXIT)) {
546 continue;
547 }
548
549 /*
550 * if the process is in a non-running type state,
551 * don't touch it.
552 */
553 if (p->p_stat != SRUN && p->p_stat != SSLEEP) {
554 continue;
555 }
556
557 /*
558 * get a limit
559 */
a200ca2b
DG
560 limit = min(p->p_rlimit[RLIMIT_RSS].rlim_cur,
561 p->p_rlimit[RLIMIT_RSS].rlim_max);
55768178
DG
562
563 /*
564 * let processes that are swapped out really be swapped out
565 * set the limit to nothing (will force a swap-out.)
566 */
567 if ((p->p_flag & SLOAD) == 0)
568 limit = 0;
569
570 size = p->p_vmspace->vm_pmap.pm_stats.resident_count * NBPG;
571 if (size >= limit) {
572 overage = (size - limit) / NBPG;
573 vm_pageout_map_deactivate_pages(&p->p_vmspace->vm_map,
a200ca2b 574 (vm_map_entry_t) 0, &overage, vm_pageout_object_deactivate_pages);
55768178
DG
575 p->p_flag |= SPAGEDAEMON;
576 goto rescanproc1;
577 }
578 p->p_flag |= SPAGEDAEMON;
579 }
a200ca2b
DG
580
581#if 0
582 if (((vm_page_free_count + vm_page_inactive_count) >=
583 (vm_page_inactive_target + vm_page_free_target)) &&
584 (vm_page_free_count >= vm_page_free_target))
585 return;
586#endif
587
55768178 588#endif
15637ed4 589
a200ca2b
DG
590 pages_freed = 0;
591
15637ed4
RG
592 /*
593 * Start scanning the inactive queue for pages we can free.
594 * We keep scanning until we have enough free pages or
595 * we have scanned through the entire queue. If we
596 * encounter dirty pages, we start cleaning them.
597 */
598
a200ca2b 599 maxlaunder = (vm_page_free_target - vm_page_free_count);
55768178 600rescan:
a200ca2b
DG
601 m = (vm_page_t) queue_first(&vm_page_queue_inactive);
602 maxscan = vm_page_inactive_count;
55768178 603 while (maxscan-- > 0) {
15637ed4
RG
604 vm_page_t next;
605
ce619eaa
DG
606
607 if (queue_end(&vm_page_queue_inactive, (queue_entry_t) m)
608 || (vm_page_free_count >= vm_page_free_target)) {
55768178
DG
609 break;
610 }
15637ed4 611
ce619eaa
DG
612 next = (vm_page_t) queue_next(&m->pageq);
613
55768178
DG
614 /*
615 * dont mess with busy pages
616 */
617 if (m->flags & PG_BUSY) {
618 queue_remove(&vm_page_queue_inactive, m, vm_page_t, pageq);
619 queue_enter(&vm_page_queue_inactive, m, vm_page_t, pageq);
ce619eaa 620 m = next;
55768178
DG
621 continue;
622 }
15637ed4 623
55768178
DG
624 /*
625 * if page is clean and but the page has been referenced,
626 * then reactivate the page, but if we are very low on memory
627 * or the page has not been referenced, then we free it to the
628 * vm system.
629 */
fd76afd7 630 if (m->flags & PG_CLEAN) {
55768178
DG
631 if ((vm_page_free_count > vm_pageout_free_min)
632 && pmap_is_referenced(VM_PAGE_TO_PHYS(m))) {
15637ed4 633 vm_page_activate(m);
55768178 634 ++vm_stat.reactivations;
ce619eaa 635 m = next;
55768178 636 continue;
15637ed4
RG
637 }
638 else {
15637ed4
RG
639 pmap_page_protect(VM_PAGE_TO_PHYS(m),
640 VM_PROT_NONE);
55768178
DG
641 vm_page_free(m);
642 ++pages_freed;
ce619eaa 643 m = next;
55768178 644 continue;
15637ed4 645 }
55768178 646 } else if ((m->flags & PG_LAUNDRY) && maxlaunder > 0) {
ce619eaa
DG
647 /*
648 * if a page has been used even if it is in the laundry,
649 * activate it.
650 */
651
652 if (pmap_is_referenced(VM_PAGE_TO_PHYS(m))) {
653 vm_page_activate(m);
a200ca2b 654 m->flags &= ~PG_LAUNDRY;
ce619eaa
DG
655 m = next;
656 continue;
657 }
658
15637ed4
RG
659 /*
660 * If a page is dirty, then it is either
661 * being washed (but not yet cleaned)
662 * or it is still in the laundry. If it is
663 * still in the laundry, then we start the
664 * cleaning operation.
665 */
666
55768178
DG
667 if (vm_pageout_clean(m,0)) {
668 --maxlaunder;
ce619eaa 669 /*
a200ca2b 670 * if the next page has been re-activated, start scanning again
ce619eaa
DG
671 */
672 if ((next->flags & PG_INACTIVE) == 0)
673 goto rescan;
55768178 674 }
ce619eaa
DG
675 } else if (pmap_is_referenced(VM_PAGE_TO_PHYS(m))) {
676 vm_page_activate(m);
55768178 677 }
ce619eaa 678 m = next;
55768178 679 }
15637ed4 680
a200ca2b
DG
681 /*
682 * now check malloc area or swap processes out if we are in low
683 * memory conditions
684 */
685 free = vm_page_free_count;
686 if (free <= vm_page_free_min) {
687 /*
688 * Be sure the pmap system is updated so
689 * we can scan the inactive queue.
690 */
691 pmap_update();
692
693 /*
694 * swap out inactive processes
695 */
696 swapout_threads();
697
698#if 0
699 /*
700 * see if malloc has anything for us
701 */
702 if (free <= vm_page_free_reserved)
703 malloc_gc();
704#endif
705 }
706
707skipfree:
55768178
DG
708 /*
709 * If we did not free any pages, but we need to do so, we grow the
710 * inactive target. But as we successfully free pages, then we
a200ca2b 711 * shrink the inactive target.
55768178 712 */
a200ca2b
DG
713 if (pages_freed == 0 && vm_page_free_count < vm_page_free_min) {
714 vm_page_inactive_target += (vm_page_free_min - vm_page_free_count);
715 if (vm_page_inactive_target > vm_page_free_target*5)
716 vm_page_inactive_target = vm_page_free_target*5;
717 } else if (pages_freed > 0) {
718 vm_page_inactive_target -= vm_page_free_min/2;
719 if (vm_page_inactive_target < vm_page_free_target*2)
720 vm_page_inactive_target = vm_page_free_target*2;
55768178 721 }
15637ed4 722
55768178
DG
723 /*
724 * Compute the page shortage. If we are still very low on memory
725 * be sure that we will move a minimal amount of pages from active
726 * to inactive.
727 */
15637ed4 728
55768178 729restart_inactivate_all:
15637ed4 730
55768178
DG
731 page_shortage = vm_page_inactive_target - vm_page_inactive_count;
732 page_shortage -= vm_page_free_count;
733
734 if (page_shortage <= 0) {
ce619eaa 735 if (pages_freed == 0 &&
55768178 736 ((vm_page_free_count + vm_page_inactive_count) <
ce619eaa 737 (vm_page_free_min + vm_page_inactive_target))) {
55768178
DG
738 page_shortage = 1;
739 } else {
740 page_shortage = 0;
741 }
742 }
736d20f2 743
55768178 744 maxscan = vm_page_active_count;
45852188 745
55768178
DG
746 /*
747 * deactivate pages that are active, but have not been used
748 * for a while.
749 */
750restart_inactivate:
751 m = (vm_page_t) queue_first(&vm_page_queue_active);
a200ca2b 752 while (maxscan-- > 0) {
736d20f2 753
a200ca2b
DG
754 if (page_shortage <= 0 &&
755 maxscan < (vm_page_active_count - minscan) )
756 break;
757
55768178
DG
758 if (queue_end(&vm_page_queue_active, (queue_entry_t) m)) {
759 break;
760 }
736d20f2 761
55768178 762 next = (vm_page_t) queue_next(&m->pageq);
15637ed4 763
55768178
DG
764 /*
765 * dont mess with pages that are busy
766 */
767 if (m->flags & PG_BUSY) {
768 m = next;
769 continue;
770 }
15637ed4 771
55768178
DG
772 /*
773 * Move some more pages from active to inactive.
774 */
15637ed4 775
55768178
DG
776 /*
777 * see if there are any pages that are able to be deactivated
778 */
ce619eaa
DG
779 /*
780 * the referenced bit is the one that say that the page
781 * has been used.
782 */
783 if (!pmap_is_referenced(VM_PAGE_TO_PHYS(m))) {
55768178 784 /*
ce619eaa
DG
785 * if the page has not been referenced, call the
786 * vm_page_pageout_deactivate routine. It might
787 * not deactivate the page every time. There is
788 * a policy associated with it.
55768178 789 */
a200ca2b
DG
790 if (page_shortage > 0) {
791 if (vm_page_pageout_deactivate(m)) {
792 /*
793 * if the page was really deactivated, then
794 * decrement the page_shortage
795 */
796 if ((m->flags & PG_ACTIVE) == 0) {
797 --page_shortage;
798 }
15637ed4 799 }
15637ed4 800 }
ce619eaa
DG
801 } else {
802 /*
803 * if the page was recently referenced, set our
804 * deactivate count and clear reference for a future
805 * check for deactivation.
806 */
a200ca2b
DG
807 vm_pageout_deact_bump(m);
808 if (page_shortage > 0 || m->deact >= (DEACT_MAX/2))
809 pmap_clear_reference(VM_PAGE_TO_PHYS(m));
ce619eaa
DG
810 queue_remove(&m->object->memq, m, vm_page_t, listq);
811 queue_enter(&m->object->memq, m, vm_page_t, listq);
812 queue_remove(&vm_page_queue_active, m, vm_page_t, pageq);
813 queue_enter(&vm_page_queue_active, m, vm_page_t, pageq);
814 }
55768178 815 m = next;
15637ed4 816 }
15637ed4 817
55768178
DG
818 vm_page_pagesfreed += pages_freed;
819}
15637ed4 820
a200ca2b
DG
821/*
822 * this code maintains a dynamic reference count per page
823 */
824void
825vm_pageout_deact_bump(vm_page_t m) {
826 if( m->deact >= DEACT_START) {
827 m->deact += 1;
828 if( m->deact > DEACT_MAX)
829 m->deact = DEACT_MAX;
830 } else {
831 m->deact += DEACT_START;
832 }
833}
834
55768178
DG
835/*
836 * optionally do a deactivate if the deactivate has been done
837 * enough to justify it.
838 */
839int
840vm_page_pageout_deactivate(m)
841 vm_page_t m;
842{
a200ca2b
DG
843
844 switch (m->deact) {
845case DEACT_FREE:
15637ed4 846 vm_page_deactivate(m);
55768178 847 return 1;
a200ca2b
DG
848case DEACT_CLEAN:
849 break;
850case DEACT_DELAY:
55768178 851 vm_page_makefault(m);
a200ca2b
DG
852case DEACT_START:
853 break;
15637ed4 854 }
a200ca2b
DG
855 --m->deact;
856 return 0;
15637ed4
RG
857}
858
859/*
860 * vm_pageout is the high level pageout daemon.
861 */
862
55768178
DG
863void
864vm_pageout()
15637ed4 865{
55768178 866 extern npendingio, swiopend;
a200ca2b 867 extern int vm_page_count;
15637ed4
RG
868 (void) spl0();
869
870 /*
871 * Initialize some paging parameters.
872 */
873
55768178
DG
874vmretry:
875 vm_page_free_min = npendingio/3;
876#ifdef VSMALL
877 vm_page_free_min = 8;
878#endif
ce619eaa 879 vm_page_free_reserved = 8;
55768178
DG
880 if (vm_page_free_min < 8)
881 vm_page_free_min = 8;
882 if (vm_page_free_min > 32)
883 vm_page_free_min = 32;
884 vm_pageout_free_min = 3;
885 vm_page_free_target = 2*vm_page_free_min + vm_page_free_reserved;
886 vm_page_inactive_target = 3*vm_page_free_min + vm_page_free_reserved;
887 vm_page_free_min += vm_page_free_reserved;
a200ca2b
DG
888 minscan = MINSCAN;
889 if (minscan > vm_page_count/3)
890 minscan = vm_page_count/3;
15637ed4
RG
891
892 /*
893 * The pageout daemon is never done, so loop
894 * forever.
895 */
896
55768178 897
15637ed4 898 while (TRUE) {
55768178
DG
899
900 splhigh();
901 if (vm_page_free_count > vm_page_free_min) {
902 wakeup((caddr_t) &vm_page_free_count);
a200ca2b 903 tsleep((caddr_t) &vm_pages_needed, PVM, "psleep", 0);
55768178
DG
904 } else {
905 if (nswiodone) {
906 spl0();
907 goto dosync;
908 }
a200ca2b 909 tsleep((caddr_t) &vm_pages_needed, PVM, "pslp1", 5);
55768178 910 }
55768178
DG
911 spl0();
912
913 vm_pager_sync();
15637ed4 914 vm_pageout_scan();
55768178 915 dosync:
15637ed4 916 vm_pager_sync();
55768178
DG
917 cnt.v_scan++;
918 wakeup((caddr_t) kmem_map);
15637ed4
RG
919 }
920}