vm_pageout.c revision 34321
118334Speter/*
290075Sobrien * Copyright (c) 1991 Regents of the University of California.
390075Sobrien * All rights reserved.
418334Speter * Copyright (c) 1994 John S. Dyson
590075Sobrien * All rights reserved.
618334Speter * Copyright (c) 1994 David Greenman
790075Sobrien * All rights reserved.
890075Sobrien *
990075Sobrien * This code is derived from software contributed to Berkeley by
1090075Sobrien * The Mach Operating System project at Carnegie-Mellon University.
1118334Speter *
1290075Sobrien * Redistribution and use in source and binary forms, with or without
1390075Sobrien * modification, are permitted provided that the following conditions
1490075Sobrien * are met:
1590075Sobrien * 1. Redistributions of source code must retain the above copyright
1618334Speter *    notice, this list of conditions and the following disclaimer.
1718334Speter * 2. Redistributions in binary form must reproduce the above copyright
1890075Sobrien *    notice, this list of conditions and the following disclaimer in the
1990075Sobrien *    documentation and/or other materials provided with the distribution.
2090075Sobrien * 3. All advertising materials mentioning features or use of this software
2118334Speter *    must display the following acknowledgement:
2218334Speter *	This product includes software developed by the University of
2350397Sobrien *	California, Berkeley and its contributors.
2450397Sobrien * 4. Neither the name of the University nor the names of its contributors
2550397Sobrien *    may be used to endorse or promote products derived from this software
2650397Sobrien *    without specific prior written permission.
2718334Speter *
2890075Sobrien * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2918334Speter * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
3018334Speter * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
3118334Speter * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
3290075Sobrien * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
3318334Speter * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
3490075Sobrien * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
3518334Speter * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
3652284Sobrien * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3718334Speter * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3818334Speter * SUCH DAMAGE.
3918334Speter *
4090075Sobrien *	from: @(#)vm_pageout.c	7.4 (Berkeley) 5/7/91
4118334Speter *
4250397Sobrien *
4390075Sobrien * Copyright (c) 1987, 1990 Carnegie-Mellon University.
4496263Sobrien * All rights reserved.
4518334Speter *
4618334Speter * Authors: Avadis Tevanian, Jr., Michael Wayne Young
4718334Speter *
4818334Speter * Permission to use, copy, modify and distribute this software and
4918334Speter * its documentation is hereby granted, provided that both the copyright
5018334Speter * notice and this permission notice appear in all copies of the
5118334Speter * software, derivative works or modified versions, and any portions
5218334Speter * thereof, and that both notices appear in supporting documentation.
5318334Speter *
5418334Speter * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
5518334Speter * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
5618334Speter * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
5718334Speter *
5818334Speter * Carnegie Mellon requests users of this software to return to
5918334Speter *
6018334Speter *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
6152284Sobrien *  School of Computer Science
6252284Sobrien *  Carnegie Mellon University
6352284Sobrien *  Pittsburgh PA 15213-3890
6452284Sobrien *
6518334Speter * any improvements or extensions that they make and grant Carnegie the
6618334Speter * rights to redistribute these changes.
6718334Speter *
6818334Speter * $Id: vm_pageout.c,v 1.118 1998/03/07 21:37:19 dyson Exp $
6918334Speter */
7018334Speter
7118334Speter/*
7218334Speter *	The proverbial page-out daemon.
7318334Speter */
7418334Speter
7518334Speter#include <sys/param.h>
7618334Speter#include <sys/systm.h>
7718334Speter#include <sys/kernel.h>
7818334Speter#include <sys/proc.h>
7918334Speter#include <sys/resourcevar.h>
8018334Speter#include <sys/signalvar.h>
8190075Sobrien#include <sys/vnode.h>
8218334Speter#include <sys/vmmeter.h>
8390075Sobrien#include <sys/sysctl.h>
8490075Sobrien
8590075Sobrien#include <vm/vm.h>
8690075Sobrien#include <vm/vm_param.h>
8718334Speter#include <vm/vm_prot.h>
8818334Speter#include <sys/lock.h>
8950397Sobrien#include <vm/vm_object.h>
9018334Speter#include <vm/vm_page.h>
9118334Speter#include <vm/vm_map.h>
9218334Speter#include <vm/vm_pageout.h>
9318334Speter#include <vm/vm_pager.h>
9418334Speter#include <vm/swap_pager.h>
9518334Speter#include <vm/vm_extern.h>
9618334Speter
9718334Speter/*
9818334Speter * System initialization
9918334Speter */
10018334Speter
10118334Speter/* the kernel process "vm_pageout"*/
10218334Speterstatic void vm_pageout __P((void));
10318334Speterstatic int vm_pageout_clean __P((vm_page_t));
10418334Speterstatic int vm_pageout_scan __P((void));
10518334Speterstatic int vm_pageout_free_page_calc __P((vm_size_t count));
10618334Speterstruct proc *pageproc;
10718334Speter
10818334Speterstatic struct kproc_desc page_kp = {
10918334Speter	"pagedaemon",
11018334Speter	vm_pageout,
11118334Speter	&pageproc
11218334Speter};
11318334SpeterSYSINIT_KT(pagedaemon, SI_SUB_KTHREAD_PAGE, SI_ORDER_FIRST, kproc_start, &page_kp)
11418334Speter
11518334Speter#if !defined(NO_SWAPPING)
11618334Speter/* the kernel process "vm_daemon"*/
11718334Speterstatic void vm_daemon __P((void));
11818334Speterstatic struct	proc *vmproc;
11918334Speter
12018334Speterstatic struct kproc_desc vm_kp = {
12118334Speter	"vmdaemon",
12290075Sobrien	vm_daemon,
12318334Speter	&vmproc
12452284Sobrien};
12518334SpeterSYSINIT_KT(vmdaemon, SI_SUB_KTHREAD_VM, SI_ORDER_FIRST, kproc_start, &vm_kp)
12618334Speter#endif
12718334Speter
12852284Sobrien
12952284Sobrienint vm_pages_needed=0;		/* Event on which pageout daemon sleeps */
13052284Sobrienint vm_pageout_deficit=0;	/* Estimated number of pages deficit */
13150397Sobrienint vm_pageout_pages_needed=0;	/* flag saying that the pageout daemon needs pages */
13252284Sobrien
13318334Speterextern int npendingio;
13418334Speter#if !defined(NO_SWAPPING)
13518334Speterstatic int vm_pageout_req_swapout;	/* XXX */
13618334Speterstatic int vm_daemon_needed;
13718334Speter#endif
13850397Sobrienextern int nswiodone;
13950397Sobrienextern int vm_swap_size;
14018334Speterextern int vfs_update_wakeup;
14118334Speterstatic int vm_pageout_stats_max=0, vm_pageout_stats_interval = 0;
14250397Sobrienstatic int vm_pageout_full_stats_interval = 0;
14350397Sobrienstatic int vm_pageout_stats_free_max=0, vm_pageout_algorithm_lru=0;
14450397Sobrienstatic int defer_swap_pageouts=0;
14550397Sobrienstatic int disable_swap_pageouts=0;
14650397Sobrien
14750397Sobrienstatic int max_page_launder=100;
14818334Speter#if defined(NO_SWAPPING)
14918334Speterstatic int vm_swap_enabled=0;
15018334Speterstatic int vm_swap_idle_enabled=0;
15118334Speter#else
15218334Speterstatic int vm_swap_enabled=1;
15318334Speterstatic int vm_swap_idle_enabled=0;
15418334Speter#endif
15518334Speter
15618334SpeterSYSCTL_INT(_vm, VM_PAGEOUT_ALGORITHM, pageout_algorithm,
15718334Speter	CTLFLAG_RW, &vm_pageout_algorithm_lru, 0, "");
15818334Speter
15918334SpeterSYSCTL_INT(_vm, OID_AUTO, pageout_stats_max,
16018334Speter	CTLFLAG_RW, &vm_pageout_stats_max, 0, "");
16118334Speter
16252284SobrienSYSCTL_INT(_vm, OID_AUTO, pageout_full_stats_interval,
16352284Sobrien	CTLFLAG_RW, &vm_pageout_full_stats_interval, 0, "");
16452284Sobrien
16552284SobrienSYSCTL_INT(_vm, OID_AUTO, pageout_stats_interval,
16652284Sobrien	CTLFLAG_RW, &vm_pageout_stats_interval, 0, "");
16718334Speter
16818334SpeterSYSCTL_INT(_vm, OID_AUTO, pageout_stats_free_max,
16918334Speter	CTLFLAG_RW, &vm_pageout_stats_free_max, 0, "");
17090075Sobrien
17152284Sobrien#if defined(NO_SWAPPING)
17252284SobrienSYSCTL_INT(_vm, VM_SWAPPING_ENABLED, swap_enabled,
17318334Speter	CTLFLAG_RD, &vm_swap_enabled, 0, "");
17418334SpeterSYSCTL_INT(_vm, OID_AUTO, swap_idle_enabled,
17552284Sobrien	CTLFLAG_RD, &vm_swap_idle_enabled, 0, "");
17652284Sobrien#else
17752284SobrienSYSCTL_INT(_vm, VM_SWAPPING_ENABLED, swap_enabled,
17852284Sobrien	CTLFLAG_RW, &vm_swap_enabled, 0, "");
17952284SobrienSYSCTL_INT(_vm, OID_AUTO, swap_idle_enabled,
18018334Speter	CTLFLAG_RW, &vm_swap_idle_enabled, 0, "");
18152284Sobrien#endif
18252284Sobrien
18352284SobrienSYSCTL_INT(_vm, OID_AUTO, defer_swapspace_pageouts,
18452284Sobrien	CTLFLAG_RW, &defer_swap_pageouts, 0, "");
18552284Sobrien
18618334SpeterSYSCTL_INT(_vm, OID_AUTO, disable_swapspace_pageouts,
18752284Sobrien	CTLFLAG_RW, &disable_swap_pageouts, 0, "");
18852284Sobrien
18952284SobrienSYSCTL_INT(_vm, OID_AUTO, max_page_launder,
19018334Speter	CTLFLAG_RW, &max_page_launder, 0, "");
19152284Sobrien
19252284Sobrien
19352284Sobrien#define VM_PAGEOUT_PAGE_COUNT 16
19452284Sobrienint vm_pageout_page_count = VM_PAGEOUT_PAGE_COUNT;
19552284Sobrien
19618334Speterint vm_page_max_wired;		/* XXX max # of wired pages system-wide */
19718334Speter
19852284Sobrien#if !defined(NO_SWAPPING)
19952284Sobrientypedef void freeer_fcn_t __P((vm_map_t, vm_object_t, vm_pindex_t, int));
20052284Sobrienstatic void vm_pageout_map_deactivate_pages __P((vm_map_t, vm_pindex_t));
20152284Sobrienstatic freeer_fcn_t vm_pageout_object_deactivate_pages;
20252284Sobrienstatic void vm_req_vmdaemon __P((void));
20352284Sobrien#endif
20450397Sobrienstatic void vm_pageout_page_stats(void);
20552284Sobrienvoid pmap_collect(void);
20652284Sobrien
20752284Sobrien/*
20852284Sobrien * vm_pageout_clean:
20952284Sobrien *
21050397Sobrien * Clean the page and remove it from the laundry.
21152284Sobrien *
21252284Sobrien * We set the busy bit to cause potential page faults on this page to
21352284Sobrien * block.
21452284Sobrien *
21518334Speter * And we set pageout-in-progress to keep the object from disappearing
21618334Speter * during pageout.  This guarantees that the page won't move from the
21718334Speter * inactive queue.  (However, any other page on the inactive queue may
21818334Speter * move!)
21918334Speter */
22018334Speterstatic int
22118334Spetervm_pageout_clean(m)
22218334Speter	vm_page_t m;
22318334Speter{
22418334Speter	register vm_object_t object;
22518334Speter	vm_page_t mc[2*vm_pageout_page_count];
22618334Speter	int pageout_count;
22718334Speter	int i, forward_okay, backward_okay, page_base;
22818334Speter	vm_pindex_t pindex = m->pindex;
22990075Sobrien
23018334Speter	object = m->object;
23118334Speter
23218334Speter	/*
23318334Speter	 * If not OBJT_SWAP, additional memory may be needed to do the pageout.
23418334Speter	 * Try to avoid the deadlock.
23518334Speter	 */
23618334Speter	if ((object->type == OBJT_DEFAULT) &&
23718334Speter	    ((cnt.v_free_count + cnt.v_cache_count) < cnt.v_pageout_free_min))
23818334Speter		return 0;
23990075Sobrien
24018334Speter	/*
24152284Sobrien	 * Don't mess with the page if it's busy.
24290075Sobrien	 */
24318334Speter	if ((m->hold_count != 0) ||
24490075Sobrien	    ((m->busy != 0) || (m->flags & PG_BUSY)))
24590075Sobrien		return 0;
24690075Sobrien
24790075Sobrien	/*
24818334Speter	 * Try collapsing before it's too late.
24918334Speter	 */
25018334Speter	if (object->backing_object) {
25118334Speter		vm_object_collapse(object);
25218334Speter	}
25318334Speter
25418334Speter	mc[vm_pageout_page_count] = m;
25518334Speter	pageout_count = 1;
25618334Speter	page_base = vm_pageout_page_count;
25718334Speter	forward_okay = TRUE;
25818334Speter	if (pindex != 0)
25918334Speter		backward_okay = TRUE;
26018334Speter	else
26118334Speter		backward_okay = FALSE;
26218334Speter	/*
26318334Speter	 * Scan object for clusterable pages.
26418334Speter	 *
26518334Speter	 * We can cluster ONLY if: ->> the page is NOT
26618334Speter	 * clean, wired, busy, held, or mapped into a
26718334Speter	 * buffer, and one of the following:
26818334Speter	 * 1) The page is inactive, or a seldom used
26952284Sobrien	 *    active page.
27018334Speter	 * -or-
27152284Sobrien	 * 2) we force the issue.
27252284Sobrien	 */
27352284Sobrien	for (i = 1; (i < vm_pageout_page_count) && (forward_okay || backward_okay); i++) {
27452284Sobrien		vm_page_t p;
27552284Sobrien
27690075Sobrien		/*
27718334Speter		 * See if forward page is clusterable.
27818334Speter		 */
27990075Sobrien		if (forward_okay) {
28090075Sobrien			/*
28190075Sobrien			 * Stop forward scan at end of object.
28290075Sobrien			 */
28318334Speter			if ((pindex + i) > object->size) {
28418334Speter				forward_okay = FALSE;
28518334Speter				goto do_backward;
28652284Sobrien			}
28752284Sobrien			p = vm_page_lookup(object, pindex + i);
28852284Sobrien			if (p) {
28952284Sobrien				if (((p->queue - p->pc) == PQ_CACHE) ||
29052284Sobrien					(p->flags & PG_BUSY) || p->busy) {
29152284Sobrien					forward_okay = FALSE;
29252284Sobrien					goto do_backward;
29352284Sobrien				}
29452284Sobrien				vm_page_test_dirty(p);
29552284Sobrien				if ((p->dirty & p->valid) != 0 &&
29652284Sobrien				    (p->queue == PQ_INACTIVE) &&
29752284Sobrien				    (p->wire_count == 0) &&
29818334Speter				    (p->hold_count == 0)) {
29918334Speter					mc[vm_pageout_page_count + i] = p;
30018334Speter					pageout_count++;
30118334Speter					if (pageout_count == vm_pageout_page_count)
30218334Speter						break;
30318334Speter				} else {
30452284Sobrien					forward_okay = FALSE;
30518334Speter				}
30650397Sobrien			} else {
30750397Sobrien				forward_okay = FALSE;
30850397Sobrien			}
30950397Sobrien		}
31018334Speterdo_backward:
31150397Sobrien		/*
31250397Sobrien		 * See if backward page is clusterable.
31350397Sobrien		 */
31450397Sobrien		if (backward_okay) {
31518334Speter			/*
31618334Speter			 * Stop backward scan at beginning of object.
31718334Speter			 */
31818334Speter			if ((pindex - i) == 0) {
31950397Sobrien				backward_okay = FALSE;
32050397Sobrien			}
32152284Sobrien			p = vm_page_lookup(object, pindex - i);
32218334Speter			if (p) {
32390075Sobrien				if (((p->queue - p->pc) == PQ_CACHE) ||
32452284Sobrien					(p->flags & PG_BUSY) || p->busy) {
32552284Sobrien					backward_okay = FALSE;
32690075Sobrien					continue;
32790075Sobrien				}
32852284Sobrien				vm_page_test_dirty(p);
32990075Sobrien				if ((p->dirty & p->valid) != 0 &&
33090075Sobrien				    (p->queue == PQ_INACTIVE) &&
33152284Sobrien				    (p->wire_count == 0) &&
33252284Sobrien				    (p->hold_count == 0)) {
33318334Speter					mc[vm_pageout_page_count - i] = p;
33418334Speter					pageout_count++;
33518334Speter					page_base--;
33618334Speter					if (pageout_count == vm_pageout_page_count)
33718334Speter						break;
33818334Speter				} else {
33918334Speter					backward_okay = FALSE;
34018334Speter				}
34118334Speter			} else {
34218334Speter				backward_okay = FALSE;
34390075Sobrien			}
34418334Speter		}
34518334Speter	}
34618334Speter
34718334Speter	/*
34852284Sobrien	 * we allow reads during pageouts...
34918334Speter	 */
35018334Speter	return vm_pageout_flush(&mc[page_base], pageout_count, 0);
35118334Speter}
35252284Sobrien
35352284Sobrienint
35452284Sobrienvm_pageout_flush(mc, count, flags)
35518334Speter	vm_page_t *mc;
35618334Speter	int count;
35718334Speter	int flags;
35818334Speter{
35918334Speter	register vm_object_t object;
36018334Speter	int pageout_status[count];
36118334Speter	int numpagedout = 0;
36218334Speter	int i;
36318334Speter
36418334Speter	for (i = 0; i < count; i++) {
36518334Speter		mc[i]->busy++;
36618334Speter		vm_page_protect(mc[i], VM_PROT_READ);
36718334Speter	}
36818334Speter
36918334Speter	object = mc[0]->object;
37090075Sobrien	object->paging_in_progress += count;
37190075Sobrien
37290075Sobrien	vm_pager_put_pages(object, mc, count,
37390075Sobrien	    (flags | ((object == kernel_object) ? OBJPC_SYNC : 0)),
37490075Sobrien	    pageout_status);
37590075Sobrien
37690075Sobrien	for (i = 0; i < count; i++) {
37790075Sobrien		vm_page_t mt = mc[i];
37890075Sobrien
37990075Sobrien		switch (pageout_status[i]) {
38052284Sobrien		case VM_PAGER_OK:
38190075Sobrien			numpagedout++;
38290075Sobrien			break;
38390075Sobrien		case VM_PAGER_PEND:
38490075Sobrien			numpagedout++;
38590075Sobrien			break;
38690075Sobrien		case VM_PAGER_BAD:
38790075Sobrien			/*
38890075Sobrien			 * Page outside of range of object. Right now we
38990075Sobrien			 * essentially lose the changes by pretending it
39090075Sobrien			 * worked.
39190075Sobrien			 */
39290075Sobrien			pmap_clear_modify(VM_PAGE_TO_PHYS(mt));
39390075Sobrien			mt->dirty = 0;
39490075Sobrien			break;
39590075Sobrien		case VM_PAGER_ERROR:
39690075Sobrien		case VM_PAGER_FAIL:
39790075Sobrien			/*
39890075Sobrien			 * If page couldn't be paged out, then reactivate the
39990075Sobrien			 * page so it doesn't clog the inactive list.  (We
40090075Sobrien			 * will try paging out it again later).
40190075Sobrien			 */
40290075Sobrien			vm_page_activate(mt);
40390075Sobrien			break;
40490075Sobrien		case VM_PAGER_AGAIN:
40590075Sobrien			break;
40690075Sobrien		}
40790075Sobrien
40890075Sobrien		/*
40990075Sobrien		 * If the operation is still going, leave the page busy to
41090075Sobrien		 * block all other accesses. Also, leave the paging in
41190075Sobrien		 * progress indicator set so that we don't attempt an object
41290075Sobrien		 * collapse.
41390075Sobrien		 */
41490075Sobrien		if (pageout_status[i] != VM_PAGER_PEND) {
41590075Sobrien			vm_object_pip_wakeup(object);
41690075Sobrien			PAGE_BWAKEUP(mt);
41790075Sobrien		}
41890075Sobrien	}
41990075Sobrien	return numpagedout;
42090075Sobrien}
42190075Sobrien
42290075Sobrien#if !defined(NO_SWAPPING)
42390075Sobrien/*
42490075Sobrien *	vm_pageout_object_deactivate_pages
42590075Sobrien *
42690075Sobrien *	deactivate enough pages to satisfy the inactive target
42790075Sobrien *	requirements or if vm_page_proc_limit is set, then
42890075Sobrien *	deactivate all of the pages in the object and its
42990075Sobrien *	backing_objects.
43090075Sobrien *
43190075Sobrien *	The object and map must be locked.
43290075Sobrien */
43390075Sobrienstatic void
43490075Sobrienvm_pageout_object_deactivate_pages(map, object, desired, map_remove_only)
43590075Sobrien	vm_map_t map;
43690075Sobrien	vm_object_t object;
43790075Sobrien	vm_pindex_t desired;
43890075Sobrien	int map_remove_only;
43990075Sobrien{
44090075Sobrien	register vm_page_t p, next;
44190075Sobrien	int rcount;
44290075Sobrien	int remove_mode;
44390075Sobrien	int s;
44490075Sobrien
44590075Sobrien	if (object->type == OBJT_DEVICE)
44690075Sobrien		return;
44790075Sobrien
44890075Sobrien	while (object) {
44990075Sobrien		if (vm_map_pmap(map)->pm_stats.resident_count <= desired)
45090075Sobrien			return;
45190075Sobrien		if (object->paging_in_progress)
45290075Sobrien			return;
45352284Sobrien
45490075Sobrien		remove_mode = map_remove_only;
45552284Sobrien		if (object->shadow_count > 1)
45690075Sobrien			remove_mode = 1;
45790075Sobrien	/*
45890075Sobrien	 * scan the objects entire memory queue
45990075Sobrien	 */
46090075Sobrien		rcount = object->resident_page_count;
46190075Sobrien		p = TAILQ_FIRST(&object->memq);
46290075Sobrien		while (p && (rcount-- > 0)) {
46396263Sobrien			int actcount;
46490075Sobrien			if (vm_map_pmap(map)->pm_stats.resident_count <= desired)
46518334Speter				return;
46618334Speter			next = TAILQ_NEXT(p, listq);
46718334Speter			cnt.v_pdpages++;
46818334Speter			if (p->wire_count != 0 ||
46918334Speter			    p->hold_count != 0 ||
47018334Speter			    p->busy != 0 ||
47190075Sobrien			    (p->flags & PG_BUSY) ||
47218334Speter			    !pmap_page_exists(vm_map_pmap(map), VM_PAGE_TO_PHYS(p))) {
47318334Speter				p = next;
47418334Speter				continue;
47518334Speter			}
47618334Speter
47790075Sobrien			actcount = pmap_ts_referenced(VM_PAGE_TO_PHYS(p));
47850397Sobrien			if (actcount) {
47950397Sobrien				p->flags |= PG_REFERENCED;
48090075Sobrien			} else if (p->flags & PG_REFERENCED) {
48190075Sobrien				actcount = 1;
48250397Sobrien			}
48318334Speter
48418334Speter			if ((p->queue != PQ_ACTIVE) &&
48518334Speter				(p->flags & PG_REFERENCED)) {
48618334Speter				vm_page_activate(p);
48718334Speter				p->act_count += actcount;
48850397Sobrien				p->flags &= ~PG_REFERENCED;
48918334Speter			} else if (p->queue == PQ_ACTIVE) {
49018334Speter				if ((p->flags & PG_REFERENCED) == 0) {
49118334Speter					p->act_count -= min(p->act_count, ACT_DECLINE);
49218334Speter					if (!remove_mode && (vm_pageout_algorithm_lru || (p->act_count == 0))) {
49350397Sobrien						vm_page_protect(p, VM_PROT_NONE);
49418334Speter						vm_page_deactivate(p);
49518334Speter					} else {
49618334Speter						s = splvm();
49718334Speter						TAILQ_REMOVE(&vm_page_queue_active, p, pageq);
49818334Speter						TAILQ_INSERT_TAIL(&vm_page_queue_active, p, pageq);
49918334Speter						splx(s);
50050397Sobrien					}
50150397Sobrien				} else {
50250397Sobrien					vm_page_activate(p);
50390075Sobrien					p->flags &= ~PG_REFERENCED;
50418334Speter					if (p->act_count < (ACT_MAX - ACT_ADVANCE))
50518334Speter						p->act_count += ACT_ADVANCE;
50618334Speter					s = splvm();
50718334Speter					TAILQ_REMOVE(&vm_page_queue_active, p, pageq);
50818334Speter					TAILQ_INSERT_TAIL(&vm_page_queue_active, p, pageq);
50918334Speter					splx(s);
51018334Speter				}
51118334Speter			} else if (p->queue == PQ_INACTIVE) {
51218334Speter				vm_page_protect(p, VM_PROT_NONE);
51318334Speter			}
51450397Sobrien			p = next;
51518334Speter		}
51652284Sobrien		object = object->backing_object;
51790075Sobrien	}
51890075Sobrien	return;
51990075Sobrien}
52052284Sobrien
52150397Sobrien/*
52252284Sobrien * deactivate some number of pages in a map, try to do it fairly, but
52352284Sobrien * that is really hard to do.
52450397Sobrien */
52552284Sobrienstatic void
52652284Sobrienvm_pageout_map_deactivate_pages(map, desired)
52752284Sobrien	vm_map_t map;
52852284Sobrien	vm_pindex_t desired;
52952284Sobrien{
53050397Sobrien	vm_map_entry_t tmpe;
53152284Sobrien	vm_object_t obj, bigobj;
53252284Sobrien
53352284Sobrien	if (lockmgr(&map->lock, LK_EXCLUSIVE | LK_NOWAIT, (void *)0, curproc)) {
53452284Sobrien		return;
53590075Sobrien	}
53690075Sobrien
53750397Sobrien	bigobj = NULL;
53852284Sobrien
53952284Sobrien	/*
54052284Sobrien	 * first, search out the biggest object, and try to free pages from
54152284Sobrien	 * that.
54252284Sobrien	 */
54352284Sobrien	tmpe = map->header.next;
54452284Sobrien	while (tmpe != &map->header) {
54552284Sobrien		if ((tmpe->eflags & (MAP_ENTRY_IS_A_MAP|MAP_ENTRY_IS_SUB_MAP)) == 0) {
54652284Sobrien			obj = tmpe->object.vm_object;
54752284Sobrien			if ((obj != NULL) && (obj->shadow_count <= 1) &&
54818334Speter				((bigobj == NULL) ||
54918334Speter				 (bigobj->resident_page_count < obj->resident_page_count))) {
55052284Sobrien				bigobj = obj;
55152284Sobrien			}
55290075Sobrien		}
55352284Sobrien		tmpe = tmpe->next;
55452284Sobrien	}
55552284Sobrien
55652284Sobrien	if (bigobj)
55752284Sobrien		vm_pageout_object_deactivate_pages(map, bigobj, desired, 0);
55890075Sobrien
55990075Sobrien	/*
56052284Sobrien	 * Next, hunt around for other pages to deactivate.  We actually
56152284Sobrien	 * do this search sort of wrong -- .text first is not the best idea.
56252284Sobrien	 */
56352284Sobrien	tmpe = map->header.next;
56452284Sobrien	while (tmpe != &map->header) {
56590075Sobrien		if (vm_map_pmap(map)->pm_stats.resident_count <= desired)
56652284Sobrien			break;
56752284Sobrien		if ((tmpe->eflags & (MAP_ENTRY_IS_A_MAP|MAP_ENTRY_IS_SUB_MAP)) == 0) {
56852284Sobrien			obj = tmpe->object.vm_object;
56952284Sobrien			if (obj)
57052284Sobrien				vm_pageout_object_deactivate_pages(map, obj, desired, 0);
57152284Sobrien		}
57252284Sobrien		tmpe = tmpe->next;
57352284Sobrien	};
57452284Sobrien
57552284Sobrien	/*
57652284Sobrien	 * Remove all mappings if a process is swapped out, this will free page
57752284Sobrien	 * table pages.
57852284Sobrien	 */
57952284Sobrien	if (desired == 0)
58052284Sobrien		pmap_remove(vm_map_pmap(map),
58152284Sobrien			VM_MIN_ADDRESS, VM_MAXUSER_ADDRESS);
58252284Sobrien	vm_map_unlock(map);
58390075Sobrien	return;
58490075Sobrien}
58590075Sobrien#endif
58690075Sobrien
58790075Sobrienvoid
58890075Sobrienvm_pageout_page_free(vm_page_t m) {
58990075Sobrien	struct vnode *vp;
59090075Sobrien	vm_object_t object;
59190075Sobrien
59290075Sobrien	object = m->object;
59390075Sobrien	object->ref_count++;
59490075Sobrien
59590075Sobrien	if (object->type == OBJT_VNODE) {
59690075Sobrien		vp = object->handle;
59790075Sobrien		vp->v_usecount++;
59890075Sobrien		if (VSHOULDBUSY(vp))
59990075Sobrien			vbusy(vp);
60090075Sobrien	}
60190075Sobrien
60290075Sobrien	m->flags |= PG_BUSY;
60390075Sobrien	vm_page_protect(m, VM_PROT_NONE);
60490075Sobrien	vm_page_free(m);
60590075Sobrien	vm_object_deallocate(object);
60690075Sobrien}
60790075Sobrien
60890075Sobrien/*
60990075Sobrien *	vm_pageout_scan does the dirty work for the pageout daemon.
61090075Sobrien */
61190075Sobrienstatic int
61290075Sobrienvm_pageout_scan()
61390075Sobrien{
61490075Sobrien	vm_page_t m, next;
61590075Sobrien	int page_shortage, addl_page_shortage, maxscan, pcount;
61690075Sobrien	int maxlaunder;
61790075Sobrien	int pages_freed;
61890075Sobrien	struct proc *p, *bigproc;
61990075Sobrien	vm_offset_t size, bigsize;
62090075Sobrien	vm_object_t object;
62190075Sobrien	int force_wakeup = 0;
62290075Sobrien	int actcount;
62390075Sobrien	int vnodes_skipped = 0;
62490075Sobrien	int s;
62590075Sobrien
62690075Sobrien	/*
62790075Sobrien	 * Do whatever cleanup that the pmap code can.
62890075Sobrien	 */
62990075Sobrien	pmap_collect();
63090075Sobrien
63190075Sobrien	/*
63290075Sobrien	 * Start scanning the inactive queue for pages we can free. We keep
63390075Sobrien	 * scanning until we have enough free pages or we have scanned through
63490075Sobrien	 * the entire queue.  If we encounter dirty pages, we start cleaning
63590075Sobrien	 * them.
63690075Sobrien	 */
63790075Sobrien
63890075Sobrien	pages_freed = 0;
63990075Sobrien	addl_page_shortage = vm_pageout_deficit;
64090075Sobrien	vm_pageout_deficit = 0;
64190075Sobrien
64290075Sobrien	if (max_page_launder == 0)
64390075Sobrien		max_page_launder = 1;
64490075Sobrien	maxlaunder = (cnt.v_inactive_target > max_page_launder) ?
64590075Sobrien	    max_page_launder : cnt.v_inactive_target;
64690075Sobrien
64752284Sobrienrescan0:
64852284Sobrien	maxscan = cnt.v_inactive_count;
64952284Sobrien	for( m = TAILQ_FIRST(&vm_page_queue_inactive);
65052284Sobrien
65152284Sobrien		(m != NULL) && (maxscan-- > 0) &&
65252284Sobrien			((cnt.v_cache_count + cnt.v_free_count) <
65352284Sobrien			(cnt.v_cache_min + cnt.v_free_target));
65452284Sobrien
65552284Sobrien		m = next) {
65652284Sobrien
65752284Sobrien		cnt.v_pdpages++;
65818334Speter
65918334Speter		if (m->queue != PQ_INACTIVE) {
66018334Speter			goto rescan0;
66118334Speter		}
66218334Speter
66318334Speter		next = TAILQ_NEXT(m, pageq);
66418334Speter
66518334Speter		if (m->hold_count) {
66618334Speter			s = splvm();
66718334Speter			TAILQ_REMOVE(&vm_page_queue_inactive, m, pageq);
66818334Speter			TAILQ_INSERT_TAIL(&vm_page_queue_inactive, m, pageq);
66918334Speter			splx(s);
67018334Speter			addl_page_shortage++;
67118334Speter			continue;
67290075Sobrien		}
67318334Speter		/*
67418334Speter		 * Dont mess with busy pages, keep in the front of the
67518334Speter		 * queue, most likely are being paged out.
67690075Sobrien		 */
67790075Sobrien		if (m->busy || (m->flags & PG_BUSY)) {
67890075Sobrien			addl_page_shortage++;
67918334Speter			continue;
68050397Sobrien		}
68150397Sobrien
68290075Sobrien		/*
68350397Sobrien		 * If the object is not being used, we ignore previous references.
68450397Sobrien		 */
68552284Sobrien		if (m->object->ref_count == 0) {
68652284Sobrien			m->flags &= ~PG_REFERENCED;
68718334Speter			pmap_clear_reference(VM_PAGE_TO_PHYS(m));
68852284Sobrien
68918334Speter		/*
69052284Sobrien		 * Otherwise, if the page has been referenced while in the inactive
69118334Speter		 * queue, we bump the "activation count" upwards, making it less
69252284Sobrien		 * likely that the page will be added back to the inactive queue
69352284Sobrien		 * prematurely again.  Here we check the page tables (or emulated
69490075Sobrien		 * bits, if any), given the upper level VM system not knowing anything
69518334Speter		 * about existing references.
69618334Speter		 */
69718334Speter		} else if (((m->flags & PG_REFERENCED) == 0) &&
69818334Speter			(actcount = pmap_ts_referenced(VM_PAGE_TO_PHYS(m)))) {
69918334Speter			vm_page_activate(m);
70018334Speter			m->act_count += (actcount + ACT_ADVANCE);
70118334Speter			continue;
70218334Speter		}
70318334Speter
70418334Speter		/*
70590075Sobrien		 * If the upper level VM system knows about any page references,
70690075Sobrien		 * we activate the page.  We also set the "activation count" higher
70718334Speter		 * than normal so that we will less likely place pages back onto the
70818334Speter		 * inactive queue again.
70918334Speter		 */
71018334Speter		if ((m->flags & PG_REFERENCED) != 0) {
71118334Speter			m->flags &= ~PG_REFERENCED;
71218334Speter			actcount = pmap_ts_referenced(VM_PAGE_TO_PHYS(m));
71318334Speter			vm_page_activate(m);
71418334Speter			m->act_count += (actcount + ACT_ADVANCE + 1);
71518334Speter			continue;
71618334Speter		}
71718334Speter
71818334Speter		/*
71950397Sobrien		 * If the upper level VM system doesn't know anything about the
72050397Sobrien		 * page being dirty, we have to check for it again.  As far as the
72150397Sobrien		 * VM code knows, any partially dirty pages are fully dirty.
72250397Sobrien		 */
72390075Sobrien		if (m->dirty == 0) {
72490075Sobrien			vm_page_test_dirty(m);
72550397Sobrien		} else if (m->dirty != 0) {
72618334Speter			m->dirty = VM_PAGE_BITS_ALL;
72718334Speter		}
72818334Speter
72918334Speter		/*
73018334Speter		 * Invalid pages can be easily freed
73118334Speter		 */
73218334Speter		if (m->valid == 0) {
73318334Speter			vm_pageout_page_free(m);
73418334Speter			cnt.v_dfree++;
73518334Speter			pages_freed++;
73690075Sobrien
73790075Sobrien		/*
73890075Sobrien		 * Clean pages can be placed onto the cache queue.
73990075Sobrien		 */
74090075Sobrien		} else if (m->dirty == 0) {
74190075Sobrien			vm_page_cache(m);
74290075Sobrien			pages_freed++;
74352284Sobrien
74452284Sobrien		/*
74552284Sobrien		 * Dirty pages need to be paged out.  Note that we clean
74690075Sobrien		 * only a limited number of pages per pagedaemon pass.
74718334Speter		 */
74852284Sobrien		} else if (maxlaunder > 0) {
74918334Speter			int written;
75018334Speter			int swap_pageouts_ok;
75118334Speter			struct vnode *vp = NULL;
75218334Speter
75390075Sobrien			object = m->object;
75490075Sobrien
75550397Sobrien			if ((object->type != OBJT_SWAP) && (object->type != OBJT_DEFAULT)) {
75618334Speter				swap_pageouts_ok = 1;
75752284Sobrien			} else {
75818334Speter				swap_pageouts_ok = !(defer_swap_pageouts || disable_swap_pageouts);
75918334Speter				swap_pageouts_ok |= (!disable_swap_pageouts && defer_swap_pageouts &&
76018334Speter					(cnt.v_free_count + cnt.v_cache_count) < cnt.v_free_min);
76118334Speter
76290075Sobrien			}
76390075Sobrien
76490075Sobrien			/*
76590075Sobrien			 * We don't bother paging objects that are "dead".  Those
76690075Sobrien			 * objects are in a "rundown" state.
76790075Sobrien			 */
76890075Sobrien			if (!swap_pageouts_ok || (object->flags & OBJ_DEAD)) {
76990075Sobrien				s = splvm();
77090075Sobrien				TAILQ_REMOVE(&vm_page_queue_inactive, m, pageq);
77150397Sobrien				TAILQ_INSERT_TAIL(&vm_page_queue_inactive, m, pageq);
77250397Sobrien				splx(s);
77350397Sobrien				continue;
77450397Sobrien			}
77518334Speter
77618334Speter			if ((object->type == OBJT_VNODE) &&
77718334Speter				(object->flags & OBJ_DEAD) == 0) {
77818334Speter				vp = object->handle;
77918334Speter				if (VOP_ISLOCKED(vp) ||
78052284Sobrien				    vget(vp, LK_EXCLUSIVE|LK_NOOBJ, curproc)) {
78152284Sobrien					if ((m->queue == PQ_INACTIVE) &&
78290075Sobrien						(m->hold_count == 0) &&
78390075Sobrien						(m->busy == 0) &&
78490075Sobrien						(m->flags & PG_BUSY) == 0) {
78590075Sobrien						s = splvm();
78690075Sobrien						TAILQ_REMOVE(&vm_page_queue_inactive, m, pageq);
78718334Speter						TAILQ_INSERT_TAIL(&vm_page_queue_inactive, m, pageq);
78818334Speter						splx(s);
78918334Speter					}
79018334Speter					if (object->flags & OBJ_MIGHTBEDIRTY)
79118334Speter						vnodes_skipped++;
79218334Speter					continue;
79318334Speter				}
79496263Sobrien
79596263Sobrien				/*
79696263Sobrien				 * The page might have been moved to another queue
79796263Sobrien				 * during potential blocking in vget() above.
79896263Sobrien				 */
79996263Sobrien				if (m->queue != PQ_INACTIVE) {
80050397Sobrien					if (object->flags & OBJ_MIGHTBEDIRTY)
80190075Sobrien						vnodes_skipped++;
80290075Sobrien					vput(vp);
80390075Sobrien					continue;
80490075Sobrien				}
80550397Sobrien
80652284Sobrien				/*
80718334Speter				 * The page may have been busied during the blocking in
80852284Sobrien				 * vput();  We don't move the page back onto the end of
80952284Sobrien				 * the queue so that statistics are more correct if we don't.
81052284Sobrien				 */
81152284Sobrien				if (m->busy || (m->flags & PG_BUSY)) {
81252284Sobrien					vput(vp);
81352284Sobrien					continue;
81452284Sobrien				}
81552284Sobrien
81652284Sobrien				/*
81752284Sobrien				 * If the page has become held, then skip it
81852284Sobrien				 */
81952284Sobrien				if (m->hold_count) {
82052284Sobrien					s = splvm();
82152284Sobrien					TAILQ_REMOVE(&vm_page_queue_inactive, m, pageq);
82218334Speter					TAILQ_INSERT_TAIL(&vm_page_queue_inactive, m, pageq);
82318334Speter					splx(s);
82418334Speter					if (object->flags & OBJ_MIGHTBEDIRTY)
82518334Speter						vnodes_skipped++;
82618334Speter					vput(vp);
82718334Speter					continue;
82818334Speter				}
82918334Speter			}
83018334Speter
83118334Speter			/*
83218334Speter			 * If a page is dirty, then it is either being washed
83318334Speter			 * (but not yet cleaned) or it is still in the
83418334Speter			 * laundry.  If it is still in the laundry, then we
83518334Speter			 * start the cleaning operation.
83652284Sobrien			 */
83752284Sobrien			written = vm_pageout_clean(m);
83818334Speter			if (vp)
83918334Speter				vput(vp);
84018334Speter
84118334Speter			maxlaunder -= written;
84218334Speter		}
84318334Speter	}
84418334Speter
84518334Speter	/*
84618334Speter	 * Compute the page shortage.  If we are still very low on memory be
84718334Speter	 * sure that we will move a minimal amount of pages from active to
84818334Speter	 * inactive.
84952284Sobrien	 */
85052284Sobrien	page_shortage = (cnt.v_inactive_target + cnt.v_cache_min) -
85152284Sobrien	    (cnt.v_free_count + cnt.v_inactive_count + cnt.v_cache_count);
85218334Speter	if (page_shortage <= 0) {
85390075Sobrien		if (pages_freed == 0) {
85418334Speter			page_shortage = cnt.v_free_min - (cnt.v_free_count + cnt.v_cache_count);
85518334Speter		} else {
85618334Speter			page_shortage = 1;
85752284Sobrien		}
85818334Speter	}
85918334Speter
86018334Speter	/*
86118334Speter	 * If the "inactive" loop finds that there is a shortage over and
86250397Sobrien	 * above the page statistics variables, then we need to accomodate
86350397Sobrien	 * that.  This avoids potential deadlocks due to pages being temporarily
86450397Sobrien	 * busy for I/O or other types of temporary wiring.
86550397Sobrien	 */
86650397Sobrien	if (addl_page_shortage) {
86718334Speter		if (page_shortage < 0)
86850397Sobrien			page_shortage = 0;
86918334Speter		page_shortage += addl_page_shortage;
87050397Sobrien	}
87150397Sobrien
87250397Sobrien	pcount = cnt.v_active_count;
87318334Speter	m = TAILQ_FIRST(&vm_page_queue_active);
87418334Speter	while ((m != NULL) && (pcount-- > 0) && (page_shortage > 0)) {
87518334Speter
87618334Speter		/*
87718334Speter		 * This is a consistancy check, and should likely be a panic
87818334Speter		 * or warning.
87918334Speter		 */
88018334Speter		if (m->queue != PQ_ACTIVE) {
88118334Speter			break;
88218334Speter		}
88318334Speter
88418334Speter		next = TAILQ_NEXT(m, pageq);
88518334Speter		/*
88618334Speter		 * Don't deactivate pages that are busy.
88718334Speter		 */
88818334Speter		if ((m->busy != 0) ||
88918334Speter		    (m->flags & PG_BUSY) ||
89090075Sobrien		    (m->hold_count != 0)) {
89118334Speter			s = splvm();
89252284Sobrien			TAILQ_REMOVE(&vm_page_queue_active, m, pageq);
89318334Speter			TAILQ_INSERT_TAIL(&vm_page_queue_active, m, pageq);
89452284Sobrien			splx(s);
89552284Sobrien			m = next;
89690075Sobrien			continue;
89718334Speter		}
89818334Speter
89918334Speter		/*
90018334Speter		 * The count for pagedaemon pages is done after checking the
90152284Sobrien		 * page for eligbility...
90218334Speter		 */
90318334Speter		cnt.v_pdpages++;
90490075Sobrien
90518334Speter		/*
90618334Speter		 * Check to see "how much" the page has been used.
90718334Speter		 */
90890075Sobrien		actcount = 0;
90918334Speter		if (m->object->ref_count != 0) {
91090075Sobrien			if (m->flags & PG_REFERENCED) {
91118334Speter				actcount += 1;
91252284Sobrien			}
91352284Sobrien			actcount += pmap_ts_referenced(VM_PAGE_TO_PHYS(m));
91452284Sobrien			if (actcount) {
91518334Speter				m->act_count += ACT_ADVANCE + actcount;
91618334Speter				if (m->act_count > ACT_MAX)
91718334Speter					m->act_count = ACT_MAX;
91818334Speter			}
91952284Sobrien		}
92018334Speter
92152284Sobrien		/*
92252284Sobrien		 * Since we have "tested" this bit, we need to clear it now.
92318334Speter		 */
92450397Sobrien		m->flags &= ~PG_REFERENCED;
92518334Speter
92690075Sobrien		/*
92750397Sobrien		 * Only if an object is currently being used, do we use the
92850397Sobrien		 * page activation count stats.
92990075Sobrien		 */
93090075Sobrien		if (actcount && (m->object->ref_count != 0)) {
93190075Sobrien			s = splvm();
93250397Sobrien			TAILQ_REMOVE(&vm_page_queue_active, m, pageq);
93350397Sobrien			TAILQ_INSERT_TAIL(&vm_page_queue_active, m, pageq);
93450397Sobrien			splx(s);
93552284Sobrien		} else {
93652284Sobrien			m->act_count -= min(m->act_count, ACT_DECLINE);
93718334Speter			if (vm_pageout_algorithm_lru ||
93818334Speter				(m->object->ref_count == 0) || (m->act_count == 0)) {
93918334Speter				page_shortage--;
94018334Speter				if (m->object->ref_count == 0) {
94118334Speter					vm_page_protect(m, VM_PROT_NONE);
94218334Speter					if (m->dirty == 0)
94318334Speter						vm_page_cache(m);
94418334Speter					else
94518334Speter						vm_page_deactivate(m);
94618334Speter				} else {
94718334Speter					vm_page_deactivate(m);
94818334Speter				}
94918334Speter			} else {
95018334Speter				s = splvm();
95118334Speter				TAILQ_REMOVE(&vm_page_queue_active, m, pageq);
95218334Speter				TAILQ_INSERT_TAIL(&vm_page_queue_active, m, pageq);
95318334Speter				splx(s);
95418334Speter			}
95518334Speter		}
95618334Speter		m = next;
95718334Speter	}
95818334Speter
95918334Speter	s = splvm();
96018334Speter	/*
96118334Speter	 * We try to maintain some *really* free pages, this allows interrupt
96218334Speter	 * code to be guaranteed space.
96318334Speter	 */
96418334Speter	while (cnt.v_free_count < cnt.v_free_reserved) {
96518334Speter		static int cache_rover = 0;
96618334Speter		m = vm_page_list_find(PQ_CACHE, cache_rover);
96718334Speter		if (!m)
96818334Speter			break;
96918334Speter		cache_rover = (cache_rover + PQ_PRIME2) & PQ_L2_MASK;
97018334Speter		vm_pageout_page_free(m);
97118334Speter		cnt.v_dfree++;
97218334Speter	}
97318334Speter	splx(s);
97418334Speter
97518334Speter#if !defined(NO_SWAPPING)
97618334Speter	/*
97718334Speter	 * Idle process swapout -- run once per second.
97818334Speter	 */
97918334Speter	if (vm_swap_idle_enabled) {
98018334Speter		static long lsec;
98118334Speter		if (time.tv_sec != lsec) {
98218334Speter			vm_pageout_req_swapout |= VM_SWAP_IDLE;
98318334Speter			vm_req_vmdaemon();
98418334Speter			lsec = time.tv_sec;
98518334Speter		}
98618334Speter	}
98718334Speter#endif
98818334Speter
98918334Speter	/*
99018334Speter	 * If we didn't get enough free pages, and we have skipped a vnode
99118334Speter	 * in a writeable object, wakeup the sync daemon.  And kick swapout
99218334Speter	 * if we did not get enough free pages.
99352284Sobrien	 */
99452284Sobrien	if ((cnt.v_cache_count + cnt.v_free_count) <
99552284Sobrien		(cnt.v_free_target + cnt.v_cache_min) ) {
99652284Sobrien		if (vnodes_skipped &&
99752284Sobrien		    (cnt.v_cache_count + cnt.v_free_count) < cnt.v_free_min) {
99818334Speter			if (!vfs_update_wakeup) {
99918334Speter				vfs_update_wakeup = 1;
100052284Sobrien				wakeup(&vfs_update_wakeup);
100118334Speter			}
100252284Sobrien		}
100352284Sobrien#if !defined(NO_SWAPPING)
100452284Sobrien		if (vm_swap_enabled &&
100518334Speter			(cnt.v_free_count + cnt.v_cache_count < cnt.v_free_target)) {
100618334Speter			vm_req_vmdaemon();
100752284Sobrien			vm_pageout_req_swapout |= VM_SWAP_NORMAL;
100818334Speter		}
100990075Sobrien#endif
101052284Sobrien	}
101118334Speter
101252284Sobrien
101318334Speter	/*
101452284Sobrien	 * make sure that we have swap space -- if we are low on memory and
101552284Sobrien	 * swap -- then kill the biggest process.
101652284Sobrien	 */
101752284Sobrien	if ((vm_swap_size == 0 || swap_pager_full) &&
101818334Speter	    ((cnt.v_free_count + cnt.v_cache_count) < cnt.v_free_min)) {
101952284Sobrien		bigproc = NULL;
102052284Sobrien		bigsize = 0;
102152284Sobrien		for (p = allproc.lh_first; p != 0; p = p->p_list.le_next) {
102252284Sobrien			/*
102352284Sobrien			 * if this is a system process, skip it
102452284Sobrien			 */
102518334Speter			if ((p->p_flag & P_SYSTEM) || (p->p_pid == 1) ||
102690075Sobrien			    ((p->p_pid < 48) && (vm_swap_size != 0))) {
102752284Sobrien				continue;
102818334Speter			}
102952284Sobrien			/*
103052284Sobrien			 * if the process is in a non-running type state,
103152284Sobrien			 * don't touch it.
103218334Speter			 */
103352284Sobrien			if (p->p_stat != SRUN && p->p_stat != SSLEEP) {
103452284Sobrien				continue;
103552284Sobrien			}
103652284Sobrien			/*
103752284Sobrien			 * get the process size
103852284Sobrien			 */
103952284Sobrien			size = p->p_vmspace->vm_pmap.pm_stats.resident_count;
104052284Sobrien			/*
104118334Speter			 * if the this process is bigger than the biggest one
104290075Sobrien			 * remember it.
104352284Sobrien			 */
104452284Sobrien			if (size > bigsize) {
104518334Speter				bigproc = p;
104652284Sobrien				bigsize = size;
104790075Sobrien			}
104818334Speter		}
104952284Sobrien		if (bigproc != NULL) {
105052284Sobrien			killproc(bigproc, "out of swap space");
105118334Speter			bigproc->p_estcpu = 0;
105252284Sobrien			bigproc->p_nice = PRIO_MIN;
105352284Sobrien			resetpriority(bigproc);
105490075Sobrien			wakeup(&cnt.v_free_count);
105590075Sobrien		}
105652284Sobrien	}
105718334Speter	return force_wakeup;
105852284Sobrien}
105952284Sobrien
106052284Sobrien/*
106152284Sobrien * This routine tries to maintain the pseudo LRU active queue,
106252284Sobrien * so that during long periods of time where there is no paging,
106352284Sobrien * that some statistic accumlation still occurs.  This code
106452284Sobrien * helps the situation where paging just starts to occur.
106552284Sobrien */
106652284Sobrienstatic void
106752284Sobrienvm_pageout_page_stats()
106852284Sobrien{
106952284Sobrien	int s;
107052284Sobrien	vm_page_t m,next;
107152284Sobrien	int pcount,tpcount;		/* Number of pages to check */
107252284Sobrien	static int fullintervalcount = 0;
107352284Sobrien
107452284Sobrien	pcount = cnt.v_active_count;
107552284Sobrien	fullintervalcount += vm_pageout_stats_interval;
107652284Sobrien	if (fullintervalcount < vm_pageout_full_stats_interval) {
107752284Sobrien		tpcount = (vm_pageout_stats_max * cnt.v_active_count) / cnt.v_page_count;
107852284Sobrien		if (pcount > tpcount)
107952284Sobrien			pcount = tpcount;
108090075Sobrien	}
108190075Sobrien
108290075Sobrien	m = TAILQ_FIRST(&vm_page_queue_active);
108390075Sobrien	while ((m != NULL) && (pcount-- > 0)) {
108490075Sobrien		int actcount;
108590075Sobrien
108690075Sobrien		if (m->queue != PQ_ACTIVE) {
108790075Sobrien			break;
108890075Sobrien		}
108990075Sobrien
109052284Sobrien		next = TAILQ_NEXT(m, pageq);
109152284Sobrien		/*
109218334Speter		 * Don't deactivate pages that are busy.
109352284Sobrien		 */
109452284Sobrien		if ((m->busy != 0) ||
109552284Sobrien		    (m->flags & PG_BUSY) ||
109618334Speter		    (m->hold_count != 0)) {
109752284Sobrien			s = splvm();
109852284Sobrien			TAILQ_REMOVE(&vm_page_queue_active, m, pageq);
109952284Sobrien			TAILQ_INSERT_TAIL(&vm_page_queue_active, m, pageq);
110018334Speter			splx(s);
110152284Sobrien			m = next;
110252284Sobrien			continue;
110352284Sobrien		}
110418334Speter
110552284Sobrien		actcount = 0;
110652284Sobrien		if (m->flags & PG_REFERENCED) {
110752284Sobrien			m->flags &= ~PG_REFERENCED;
110890075Sobrien			actcount += 1;
110918334Speter		}
111052284Sobrien
111118334Speter		actcount += pmap_ts_referenced(VM_PAGE_TO_PHYS(m));
111252284Sobrien		if (actcount) {
111352284Sobrien			m->act_count += ACT_ADVANCE + actcount;
111418334Speter			if (m->act_count > ACT_MAX)
111552284Sobrien				m->act_count = ACT_MAX;
111652284Sobrien			s = splvm();
111752284Sobrien			TAILQ_REMOVE(&vm_page_queue_active, m, pageq);
111818334Speter			TAILQ_INSERT_TAIL(&vm_page_queue_active, m, pageq);
111952284Sobrien			splx(s);
112052284Sobrien		} else {
112152284Sobrien			if (m->act_count == 0) {
112252284Sobrien				/*
112352284Sobrien				 * We turn off page access, so that we have more accurate
112418334Speter				 * RSS stats.  We don't do this in the normal page deactivation
112552284Sobrien				 * when the system is loaded VM wise, because the cost of
112652284Sobrien				 * the large number of page protect operations would be higher
112752284Sobrien				 * than the value of doing the operation.
112852284Sobrien				 */
112918334Speter				vm_page_protect(m, VM_PROT_NONE);
113052284Sobrien				vm_page_deactivate(m);
113152284Sobrien			} else {
113252284Sobrien				m->act_count -= min(m->act_count, ACT_DECLINE);
113318334Speter				s = splvm();
113490075Sobrien				TAILQ_REMOVE(&vm_page_queue_active, m, pageq);
113552284Sobrien				TAILQ_INSERT_TAIL(&vm_page_queue_active, m, pageq);
113618334Speter				splx(s);
113752284Sobrien			}
113852284Sobrien		}
113952284Sobrien
114052284Sobrien		m = next;
114118334Speter	}
114252284Sobrien}
114352284Sobrien
114452284Sobrienstatic int
114552284Sobrienvm_pageout_free_page_calc(count)
114618334Spetervm_size_t count;
114752284Sobrien{
114852284Sobrien	if (count < cnt.v_page_count)
114952284Sobrien		 return 0;
115018334Speter	/*
115152284Sobrien	 * free_reserved needs to include enough for the largest swap pager
115252284Sobrien	 * structures plus enough for any pv_entry structs when paging.
115318334Speter	 */
115452284Sobrien	if (cnt.v_page_count > 1024)
115552284Sobrien		cnt.v_free_min = 4 + (cnt.v_page_count - 1024) / 200;
115618334Speter	else
115752284Sobrien		cnt.v_free_min = 4;
115852284Sobrien	cnt.v_pageout_free_min = (2*MAXBSIZE)/PAGE_SIZE +
115952284Sobrien		cnt.v_interrupt_free_min;
116052284Sobrien	cnt.v_free_reserved = vm_pageout_page_count +
116152284Sobrien		cnt.v_pageout_free_min + (count / 768) + PQ_L2_SIZE;
116290075Sobrien	cnt.v_free_min += cnt.v_free_reserved;
116390075Sobrien	return 1;
116452284Sobrien}
116552284Sobrien
116690075Sobrien
116790075Sobrien/*
116890075Sobrien *	vm_pageout is the high level pageout daemon.
116990075Sobrien */
117090075Sobrienstatic void
117190075Sobrienvm_pageout()
117290075Sobrien{
117390075Sobrien	/*
117452284Sobrien	 * Initialize some paging parameters.
117552284Sobrien	 */
117652284Sobrien
117752284Sobrien	cnt.v_interrupt_free_min = 2;
117852284Sobrien	if (cnt.v_page_count < 2000)
117918334Speter		vm_pageout_page_count = 8;
118052284Sobrien
118152284Sobrien	vm_pageout_free_page_calc(cnt.v_page_count);
118252284Sobrien	/*
118352284Sobrien	 * free_reserved needs to include enough for the largest swap pager
118418334Speter	 * structures plus enough for any pv_entry structs when paging.
118590075Sobrien	 */
118690075Sobrien	if (cnt.v_free_count > 6144)
118790075Sobrien		cnt.v_free_target = 3 * cnt.v_free_min + cnt.v_free_reserved;
118890075Sobrien	else
118990075Sobrien		cnt.v_free_target = 2 * cnt.v_free_min + cnt.v_free_reserved;
119090075Sobrien
119118334Speter	if (cnt.v_free_count > 2048) {
119252284Sobrien		cnt.v_cache_min = cnt.v_free_target;
119390075Sobrien		cnt.v_cache_max = 2 * cnt.v_cache_min;
119452284Sobrien		cnt.v_inactive_target = (3 * cnt.v_free_target) / 2;
119552284Sobrien	} else {
119618334Speter		cnt.v_cache_min = 0;
119790075Sobrien		cnt.v_cache_max = 0;
119890075Sobrien		cnt.v_inactive_target = cnt.v_free_count / 4;
119990075Sobrien	}
120090075Sobrien	if (cnt.v_inactive_target > cnt.v_free_count / 3)
120190075Sobrien		cnt.v_inactive_target = cnt.v_free_count / 3;
120252284Sobrien
120390075Sobrien	/* XXX does not really belong here */
120490075Sobrien	if (vm_page_max_wired == 0)
120590075Sobrien		vm_page_max_wired = cnt.v_free_count / 3;
120690075Sobrien
120790075Sobrien	if (vm_pageout_stats_max == 0)
120890075Sobrien		vm_pageout_stats_max = cnt.v_free_target;
120952284Sobrien
121090075Sobrien	/*
121152284Sobrien	 * Set interval in seconds for stats scan.
121252284Sobrien	 */
121318334Speter	if (vm_pageout_stats_interval == 0)
121452284Sobrien		vm_pageout_stats_interval = 4;
121552284Sobrien	if (vm_pageout_full_stats_interval == 0)
121652284Sobrien		vm_pageout_full_stats_interval = vm_pageout_stats_interval * 4;
121752284Sobrien
121852284Sobrien
121952284Sobrien	/*
122052284Sobrien	 * Set maximum free per pass
122152284Sobrien	 */
122252284Sobrien	if (vm_pageout_stats_free_max == 0)
122352284Sobrien		vm_pageout_stats_free_max = 25;
122452284Sobrien
122552284Sobrien	max_page_launder = (cnt.v_page_count > 1800 ? 32 : 16);
122618334Speter
122752284Sobrien	swap_pager_swap_init();
122852284Sobrien	/*
122952284Sobrien	 * The pageout daemon is never done, so loop forever.
123018334Speter	 */
123152284Sobrien	while (TRUE) {
123252284Sobrien		int inactive_target;
123352284Sobrien		int error;
123418334Speter		int s = splvm();
123552284Sobrien		if (!vm_pages_needed ||
123652284Sobrien			((cnt.v_free_count + cnt.v_cache_count) > cnt.v_free_min)) {
123752284Sobrien			vm_pages_needed = 0;
123852284Sobrien			error = tsleep(&vm_pages_needed,
123952284Sobrien				PVM, "psleep", vm_pageout_stats_interval * hz);
124090075Sobrien			if (error && !vm_pages_needed) {
124190075Sobrien				splx(s);
124252284Sobrien				vm_pageout_page_stats();
124352284Sobrien				continue;
124452284Sobrien			}
124518334Speter		} else if (vm_pages_needed) {
124652284Sobrien			vm_pages_needed = 0;
124790075Sobrien			tsleep(&vm_pages_needed, PVM, "psleep", hz/2);
124852284Sobrien		}
124952284Sobrien
125052284Sobrien		if (vm_pages_needed)
125152284Sobrien			cnt.v_pdwakeups++;
125252284Sobrien		vm_pages_needed = 0;
125352284Sobrien		splx(s);
125452284Sobrien		vm_pager_sync();
125552284Sobrien		vm_pageout_scan();
125618334Speter		vm_pageout_deficit = 0;
125752284Sobrien		vm_pager_sync();
125852284Sobrien		wakeup(&cnt.v_free_count);
125952284Sobrien	}
126052284Sobrien}
126152284Sobrien
126252284Sobrienvoid
126352284Sobrienpagedaemon_wakeup()
126418334Speter{
126552284Sobrien	if (!vm_pages_needed && curproc != pageproc) {
126652284Sobrien		vm_pages_needed++;
126752284Sobrien		wakeup(&vm_pages_needed);
126852284Sobrien	}
126918334Speter}
127052284Sobrien
127152284Sobrien#if !defined(NO_SWAPPING)
127252284Sobrienstatic void
127352284Sobrienvm_req_vmdaemon()
127452284Sobrien{
127552284Sobrien	static int lastrun = 0;
127652284Sobrien
127718334Speter	if ((ticks > (lastrun + hz)) || (ticks < lastrun)) {
127852284Sobrien		wakeup(&vm_daemon_needed);
127952284Sobrien		lastrun = ticks;
128052284Sobrien	}
128118334Speter}
128252284Sobrien
128352284Sobrienstatic void
128452284Sobrienvm_daemon()
128590075Sobrien{
128618334Speter	vm_object_t object;
128796263Sobrien	struct proc *p;
128896263Sobrien
128996263Sobrien	while (TRUE) {
129096263Sobrien		tsleep(&vm_daemon_needed, PUSER, "psleep", 0);
129196263Sobrien		if (vm_pageout_req_swapout) {
129252284Sobrien			swapout_procs(vm_pageout_req_swapout);
129352284Sobrien			vm_pageout_req_swapout = 0;
129418334Speter		}
129552284Sobrien		/*
129652284Sobrien		 * scan the processes for exceeding their rlimits or if
129752284Sobrien		 * process is swapped out -- deactivate pages
129852284Sobrien		 */
129952284Sobrien
130052284Sobrien		for (p = allproc.lh_first; p != 0; p = p->p_list.le_next) {
130190075Sobrien			quad_t limit;
130252284Sobrien			vm_offset_t size;
130352284Sobrien
130452284Sobrien			/*
130552284Sobrien			 * if this is a system process or if we have already
130690075Sobrien			 * looked at this process, skip it.
130752284Sobrien			 */
130852284Sobrien			if (p->p_flag & (P_SYSTEM | P_WEXIT)) {
130918334Speter				continue;
131052284Sobrien			}
131152284Sobrien			/*
131252284Sobrien			 * if the process is in a non-running type state,
131352284Sobrien			 * don't touch it.
131452284Sobrien			 */
131518334Speter			if (p->p_stat != SRUN && p->p_stat != SSLEEP) {
131690075Sobrien				continue;
131752284Sobrien			}
131852284Sobrien			/*
131952284Sobrien			 * get a limit
132052284Sobrien			 */
132152284Sobrien			limit = qmin(p->p_rlimit[RLIMIT_RSS].rlim_cur,
132218334Speter			    p->p_rlimit[RLIMIT_RSS].rlim_max);
132352284Sobrien
132452284Sobrien			/*
132518334Speter			 * let processes that are swapped out really be
132652284Sobrien			 * swapped out set the limit to nothing (will force a
132752284Sobrien			 * swap-out.)
132852284Sobrien			 */
132952284Sobrien			if ((p->p_flag & P_INMEM) == 0)
133052284Sobrien				limit = 0;	/* XXX */
133152284Sobrien
133252284Sobrien			size = p->p_vmspace->vm_pmap.pm_stats.resident_count * PAGE_SIZE;
133318334Speter			if (limit >= 0 && size >= limit) {
133452284Sobrien				vm_pageout_map_deactivate_pages(&p->p_vmspace->vm_map,
133590075Sobrien				    (vm_pindex_t)(limit >> PAGE_SHIFT) );
133652284Sobrien			}
133718334Speter		}
133852284Sobrien	}
133952284Sobrien}
134052284Sobrien#endif
134190075Sobrien