vm_page.c revision 13490
1/*
2 * Copyright (c) 1991 Regents of the University of California.
3 * All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * The Mach Operating System project at Carnegie-Mellon University.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 *    notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 *    notice, this list of conditions and the following disclaimer in the
15 *    documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 *    must display the following acknowledgement:
18 *	This product includes software developed by the University of
19 *	California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 *    may be used to endorse or promote products derived from this software
22 *    without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 *
36 *	from: @(#)vm_page.c	7.4 (Berkeley) 5/7/91
37 *	$Id: vm_page.c,v 1.45 1996/01/04 21:13:23 wollman Exp $
38 */
39
40/*
41 * Copyright (c) 1987, 1990 Carnegie-Mellon University.
42 * All rights reserved.
43 *
44 * Authors: Avadis Tevanian, Jr., Michael Wayne Young
45 *
46 * Permission to use, copy, modify and distribute this software and
47 * its documentation is hereby granted, provided that both the copyright
48 * notice and this permission notice appear in all copies of the
49 * software, derivative works or modified versions, and any portions
50 * thereof, and that both notices appear in supporting documentation.
51 *
52 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
53 * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
54 * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
55 *
56 * Carnegie Mellon requests users of this software to return to
57 *
58 *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
59 *  School of Computer Science
60 *  Carnegie Mellon University
61 *  Pittsburgh PA 15213-3890
62 *
63 * any improvements or extensions that they make and grant Carnegie the
64 * rights to redistribute these changes.
65 */
66
67/*
68 *	Resident memory management module.
69 */
70#include "opt_ddb.h"
71
72#include <sys/param.h>
73#include <sys/systm.h>
74#include <sys/proc.h>
75#include <sys/queue.h>
76#include <sys/vmmeter.h>
77
78#include <vm/vm.h>
79#include <vm/vm_param.h>
80#include <vm/vm_prot.h>
81#include <vm/lock.h>
82#include <vm/vm_kern.h>
83#include <vm/vm_object.h>
84#include <vm/vm_page.h>
85#include <vm/vm_map.h>
86#include <vm/vm_pageout.h>
87#include <vm/vm_extern.h>
88
89#ifdef DDB
90extern void	DDB_print_page_info __P((void));
91#endif
92
93/*
94 *	Associated with page of user-allocatable memory is a
95 *	page structure.
96 */
97
98static struct pglist *vm_page_buckets;	/* Array of buckets */
99static int vm_page_bucket_count;	/* How big is array? */
100static int vm_page_hash_mask;		/* Mask for hash function */
101
102struct pglist vm_page_queue_free;
103struct pglist vm_page_queue_zero;
104struct pglist vm_page_queue_active;
105struct pglist vm_page_queue_inactive;
106struct pglist vm_page_queue_cache;
107
108int no_queue;
109
110struct {
111	struct pglist *pl;
112	int	*cnt;
113} vm_page_queues[PQ_CACHE+1] = {
114	{NULL, &no_queue},
115	{ &vm_page_queue_free, &cnt.v_free_count},
116	{ &vm_page_queue_zero, &cnt.v_free_count},
117	{ &vm_page_queue_inactive, &cnt.v_inactive_count},
118	{ &vm_page_queue_active, &cnt.v_active_count},
119	{ &vm_page_queue_cache, &cnt.v_cache_count}
120};
121
122vm_page_t vm_page_array;
123static int vm_page_array_size;
124long first_page;
125static long last_page;
126static vm_size_t page_mask;
127static int page_shift;
128int vm_page_zero_count;
129
130/*
131 * map of contiguous valid DEV_BSIZE chunks in a page
132 * (this list is valid for page sizes upto 16*DEV_BSIZE)
133 */
134static u_short vm_page_dev_bsize_chunks[] = {
135	0x0, 0x1, 0x3, 0x7, 0xf, 0x1f, 0x3f, 0x7f, 0xff,
136	0x1ff, 0x3ff, 0x7ff, 0xfff, 0x1fff, 0x3fff, 0x7fff, 0xffff
137};
138
139static inline __pure int
140		vm_page_hash __P((vm_object_t object, vm_pindex_t pindex))
141		__pure2;
142static void	vm_page_unqueue __P((vm_page_t ));
143
144/*
145 *	vm_set_page_size:
146 *
147 *	Sets the page size, perhaps based upon the memory
148 *	size.  Must be called before any use of page-size
149 *	dependent functions.
150 *
151 *	Sets page_shift and page_mask from cnt.v_page_size.
152 */
153void
154vm_set_page_size()
155{
156
157	if (cnt.v_page_size == 0)
158		cnt.v_page_size = DEFAULT_PAGE_SIZE;
159	page_mask = cnt.v_page_size - 1;
160	if ((page_mask & cnt.v_page_size) != 0)
161		panic("vm_set_page_size: page size not a power of two");
162	for (page_shift = 0;; page_shift++)
163		if ((1 << page_shift) == cnt.v_page_size)
164			break;
165}
166
167/*
168 *	vm_page_startup:
169 *
170 *	Initializes the resident memory module.
171 *
172 *	Allocates memory for the page cells, and
173 *	for the object/offset-to-page hash table headers.
174 *	Each page cell is initialized and placed on the free list.
175 */
176
177vm_offset_t
178vm_page_startup(starta, enda, vaddr)
179	register vm_offset_t starta;
180	vm_offset_t enda;
181	register vm_offset_t vaddr;
182{
183	register vm_offset_t mapped;
184	register vm_page_t m;
185	register struct pglist *bucket;
186	vm_size_t npages, page_range;
187	register vm_offset_t new_start;
188	int i;
189	vm_offset_t pa;
190	int nblocks;
191	vm_offset_t first_managed_page;
192
193	/* the biggest memory array is the second group of pages */
194	vm_offset_t start;
195	vm_offset_t biggestone, biggestsize;
196
197	vm_offset_t total;
198
199	total = 0;
200	biggestsize = 0;
201	biggestone = 0;
202	nblocks = 0;
203	vaddr = round_page(vaddr);
204
205	for (i = 0; phys_avail[i + 1]; i += 2) {
206		phys_avail[i] = round_page(phys_avail[i]);
207		phys_avail[i + 1] = trunc_page(phys_avail[i + 1]);
208	}
209
210	for (i = 0; phys_avail[i + 1]; i += 2) {
211		int size = phys_avail[i + 1] - phys_avail[i];
212
213		if (size > biggestsize) {
214			biggestone = i;
215			biggestsize = size;
216		}
217		++nblocks;
218		total += size;
219	}
220
221	start = phys_avail[biggestone];
222
223	/*
224	 * Initialize the queue headers for the free queue, the active queue
225	 * and the inactive queue.
226	 */
227
228	TAILQ_INIT(&vm_page_queue_free);
229	TAILQ_INIT(&vm_page_queue_zero);
230	TAILQ_INIT(&vm_page_queue_active);
231	TAILQ_INIT(&vm_page_queue_inactive);
232	TAILQ_INIT(&vm_page_queue_cache);
233
234	/*
235	 * Allocate (and initialize) the hash table buckets.
236	 *
237	 * The number of buckets MUST BE a power of 2, and the actual value is
238	 * the next power of 2 greater than the number of physical pages in
239	 * the system.
240	 *
241	 * Note: This computation can be tweaked if desired.
242	 */
243	vm_page_buckets = (struct pglist *) vaddr;
244	bucket = vm_page_buckets;
245	if (vm_page_bucket_count == 0) {
246		vm_page_bucket_count = 2;
247		while (vm_page_bucket_count < atop(total))
248			vm_page_bucket_count <<= 1;
249	}
250	vm_page_hash_mask = vm_page_bucket_count - 1;
251
252	/*
253	 * Validate these addresses.
254	 */
255
256	new_start = start + vm_page_bucket_count * sizeof(struct pglist);
257	new_start = round_page(new_start);
258	mapped = vaddr;
259	vaddr = pmap_map(mapped, start, new_start,
260	    VM_PROT_READ | VM_PROT_WRITE);
261	start = new_start;
262	bzero((caddr_t) mapped, vaddr - mapped);
263	mapped = vaddr;
264
265	for (i = 0; i < vm_page_bucket_count; i++) {
266		TAILQ_INIT(bucket);
267		bucket++;
268	}
269
270	/*
271	 * round (or truncate) the addresses to our page size.
272	 */
273
274	/*
275	 * Pre-allocate maps and map entries that cannot be dynamically
276	 * allocated via malloc().  The maps include the kernel_map and
277	 * kmem_map which must be initialized before malloc() will work
278	 * (obviously).  Also could include pager maps which would be
279	 * allocated before kmeminit.
280	 *
281	 * Allow some kernel map entries... this should be plenty since people
282	 * shouldn't be cluttering up the kernel map (they should use their
283	 * own maps).
284	 */
285
286	kentry_data_size = MAX_KMAP * sizeof(struct vm_map) +
287	    MAX_KMAPENT * sizeof(struct vm_map_entry);
288	kentry_data_size = round_page(kentry_data_size);
289	kentry_data = (vm_offset_t) vaddr;
290	vaddr += kentry_data_size;
291
292	/*
293	 * Validate these zone addresses.
294	 */
295
296	new_start = start + (vaddr - mapped);
297	pmap_map(mapped, start, new_start, VM_PROT_READ | VM_PROT_WRITE);
298	bzero((caddr_t) mapped, (vaddr - mapped));
299	start = round_page(new_start);
300
301	/*
302	 * Compute the number of pages of memory that will be available for
303	 * use (taking into account the overhead of a page structure per
304	 * page).
305	 */
306
307	first_page = phys_avail[0] / PAGE_SIZE;
308	last_page = phys_avail[(nblocks - 1) * 2 + 1] / PAGE_SIZE;
309
310	page_range = last_page - (phys_avail[0] / PAGE_SIZE);
311	npages = (total - (page_range * sizeof(struct vm_page)) -
312	    (start - phys_avail[biggestone])) / PAGE_SIZE;
313
314	/*
315	 * Initialize the mem entry structures now, and put them in the free
316	 * queue.
317	 */
318
319	vm_page_array = (vm_page_t) vaddr;
320	mapped = vaddr;
321
322	/*
323	 * Validate these addresses.
324	 */
325
326	new_start = round_page(start + page_range * sizeof(struct vm_page));
327	mapped = pmap_map(mapped, start, new_start,
328	    VM_PROT_READ | VM_PROT_WRITE);
329	start = new_start;
330
331	first_managed_page = start / PAGE_SIZE;
332
333	/*
334	 * Clear all of the page structures
335	 */
336	bzero((caddr_t) vm_page_array, page_range * sizeof(struct vm_page));
337	vm_page_array_size = page_range;
338
339	cnt.v_page_count = 0;
340	cnt.v_free_count = 0;
341	for (i = 0; phys_avail[i + 1] && npages > 0; i += 2) {
342		if (i == biggestone)
343			pa = ptoa(first_managed_page);
344		else
345			pa = phys_avail[i];
346		while (pa < phys_avail[i + 1] && npages-- > 0) {
347			++cnt.v_page_count;
348			++cnt.v_free_count;
349			m = PHYS_TO_VM_PAGE(pa);
350			m->queue = PQ_FREE;
351			m->flags = 0;
352			m->phys_addr = pa;
353			TAILQ_INSERT_TAIL(&vm_page_queue_free, m, pageq);
354			pa += PAGE_SIZE;
355		}
356	}
357
358	return (mapped);
359}
360
361/*
362 *	vm_page_hash:
363 *
364 *	Distributes the object/offset key pair among hash buckets.
365 *
366 *	NOTE:  This macro depends on vm_page_bucket_count being a power of 2.
367 */
368static inline __pure int
369vm_page_hash(object, pindex)
370	vm_object_t object;
371	vm_pindex_t pindex;
372{
373	return ((unsigned) object + pindex) & vm_page_hash_mask;
374}
375
376/*
377 *	vm_page_insert:		[ internal use only ]
378 *
379 *	Inserts the given mem entry into the object/object-page
380 *	table and object list.
381 *
382 *	The object and page must be locked, and must be splhigh.
383 */
384
385inline void
386vm_page_insert(m, object, pindex)
387	register vm_page_t m;
388	register vm_object_t object;
389	register vm_pindex_t pindex;
390{
391	register struct pglist *bucket;
392
393	if (m->flags & PG_TABLED)
394		panic("vm_page_insert: already inserted");
395
396	/*
397	 * Record the object/offset pair in this page
398	 */
399
400	m->object = object;
401	m->pindex = pindex;
402
403	/*
404	 * Insert it into the object_object/offset hash table
405	 */
406
407	bucket = &vm_page_buckets[vm_page_hash(object, pindex)];
408	TAILQ_INSERT_TAIL(bucket, m, hashq);
409
410	/*
411	 * Now link into the object's list of backed pages.
412	 */
413
414	TAILQ_INSERT_TAIL(&object->memq, m, listq);
415	m->flags |= PG_TABLED;
416
417	/*
418	 * And show that the object has one more resident page.
419	 */
420
421	object->resident_page_count++;
422}
423
424/*
425 *	vm_page_remove:		[ internal use only ]
426 *				NOTE: used by device pager as well -wfj
427 *
428 *	Removes the given mem entry from the object/offset-page
429 *	table and the object page list.
430 *
431 *	The object and page must be locked, and at splhigh.
432 */
433
434inline void
435vm_page_remove(m)
436	register vm_page_t m;
437{
438	register struct pglist *bucket;
439
440	if (!(m->flags & PG_TABLED))
441		return;
442
443	/*
444	 * Remove from the object_object/offset hash table
445	 */
446
447	bucket = &vm_page_buckets[vm_page_hash(m->object, m->pindex)];
448	TAILQ_REMOVE(bucket, m, hashq);
449
450	/*
451	 * Now remove from the object's list of backed pages.
452	 */
453
454	TAILQ_REMOVE(&m->object->memq, m, listq);
455
456	/*
457	 * And show that the object has one fewer resident page.
458	 */
459
460	m->object->resident_page_count--;
461
462	m->flags &= ~PG_TABLED;
463}
464
465/*
466 *	vm_page_lookup:
467 *
468 *	Returns the page associated with the object/offset
469 *	pair specified; if none is found, NULL is returned.
470 *
471 *	The object must be locked.  No side effects.
472 */
473
474vm_page_t
475vm_page_lookup(object, pindex)
476	register vm_object_t object;
477	register vm_pindex_t pindex;
478{
479	register vm_page_t m;
480	register struct pglist *bucket;
481	int s;
482
483	/*
484	 * Search the hash table for this object/offset pair
485	 */
486
487	bucket = &vm_page_buckets[vm_page_hash(object, pindex)];
488
489	s = splhigh();
490	for (m = bucket->tqh_first; m != NULL; m = m->hashq.tqe_next) {
491		if ((m->object == object) && (m->pindex == pindex)) {
492			splx(s);
493			return (m);
494		}
495	}
496
497	splx(s);
498	return (NULL);
499}
500
501/*
502 *	vm_page_rename:
503 *
504 *	Move the given memory entry from its
505 *	current object to the specified target object/offset.
506 *
507 *	The object must be locked.
508 */
509void
510vm_page_rename(m, new_object, new_pindex)
511	register vm_page_t m;
512	register vm_object_t new_object;
513	vm_pindex_t new_pindex;
514{
515	int s;
516
517	s = splhigh();
518	vm_page_remove(m);
519	vm_page_insert(m, new_object, new_pindex);
520	splx(s);
521}
522
523/*
524 * vm_page_unqueue must be called at splhigh();
525 */
526static inline void
527vm_page_unqueue(vm_page_t m)
528{
529	int queue = m->queue;
530	if (queue == PQ_NONE)
531		return;
532	m->queue = PQ_NONE;
533	TAILQ_REMOVE(vm_page_queues[queue].pl, m, pageq);
534	--(*vm_page_queues[queue].cnt);
535	if (queue == PQ_CACHE) {
536		if ((cnt.v_cache_count + cnt.v_free_count) <
537			(cnt.v_free_min + cnt.v_cache_min))
538			pagedaemon_wakeup();
539	}
540	return;
541}
542
543/*
544 *	vm_page_alloc:
545 *
546 *	Allocate and return a memory cell associated
547 *	with this VM object/offset pair.
548 *
549 *	page_req classes:
550 *	VM_ALLOC_NORMAL		normal process request
551 *	VM_ALLOC_SYSTEM		system *really* needs a page
552 *	VM_ALLOC_INTERRUPT	interrupt time request
553 *	VM_ALLOC_ZERO		zero page
554 *
555 *	Object must be locked.
556 */
557vm_page_t
558vm_page_alloc(object, pindex, page_req)
559	vm_object_t object;
560	vm_pindex_t pindex;
561	int page_req;
562{
563	register vm_page_t m;
564	int queue;
565	int s;
566
567#ifdef DIAGNOSTIC
568	m = vm_page_lookup(object, pindex);
569	if (m)
570		panic("vm_page_alloc: page already allocated");
571#endif
572
573	if ((curproc == pageproc) && (page_req != VM_ALLOC_INTERRUPT)) {
574		page_req = VM_ALLOC_SYSTEM;
575	};
576
577	s = splhigh();
578
579	switch (page_req) {
580
581	case VM_ALLOC_NORMAL:
582		if (cnt.v_free_count >= cnt.v_free_reserved) {
583			m = vm_page_queue_free.tqh_first;
584			if (m == NULL) {
585				--vm_page_zero_count;
586				m = vm_page_queue_zero.tqh_first;
587			}
588		} else {
589			m = vm_page_queue_cache.tqh_first;
590			if (m == NULL) {
591				splx(s);
592				pagedaemon_wakeup();
593				return (NULL);
594			}
595		}
596		break;
597
598	case VM_ALLOC_ZERO:
599		if (cnt.v_free_count >= cnt.v_free_reserved) {
600			m = vm_page_queue_zero.tqh_first;
601			if (m) {
602				--vm_page_zero_count;
603			} else {
604				m = vm_page_queue_free.tqh_first;
605			}
606		} else {
607			m = vm_page_queue_cache.tqh_first;
608			if (m == NULL) {
609				splx(s);
610				pagedaemon_wakeup();
611				return (NULL);
612			}
613		}
614		break;
615
616	case VM_ALLOC_SYSTEM:
617		if ((cnt.v_free_count >= cnt.v_free_reserved) ||
618		    ((cnt.v_cache_count == 0) &&
619		    (cnt.v_free_count >= cnt.v_interrupt_free_min))) {
620				m = vm_page_queue_free.tqh_first;
621				if (m == NULL) {
622					--vm_page_zero_count;
623					m = vm_page_queue_zero.tqh_first;
624				}
625		} else {
626			m = vm_page_queue_cache.tqh_first;
627			if (m == NULL) {
628				splx(s);
629				pagedaemon_wakeup();
630				return (NULL);
631			}
632		}
633		break;
634
635	case VM_ALLOC_INTERRUPT:
636		if (cnt.v_free_count > 0) {
637			m = vm_page_queue_free.tqh_first;
638			if (m == NULL) {
639				--vm_page_zero_count;
640				m = vm_page_queue_zero.tqh_first;
641			}
642		} else {
643			splx(s);
644			pagedaemon_wakeup();
645			return (NULL);
646		}
647		break;
648
649	default:
650		panic("vm_page_alloc: invalid allocation class");
651	}
652
653	queue = m->queue;
654	TAILQ_REMOVE(vm_page_queues[queue].pl, m, pageq);
655	--(*vm_page_queues[queue].cnt);
656	if (queue == PQ_ZERO) {
657		m->flags = PG_ZERO|PG_BUSY;
658	} else if (queue == PQ_CACHE) {
659		vm_page_remove(m);
660		m->flags = PG_BUSY;
661	} else {
662		m->flags = PG_BUSY;
663	}
664	m->wire_count = 0;
665	m->hold_count = 0;
666	m->act_count = 0;
667	m->busy = 0;
668	m->valid = 0;
669	m->dirty = 0;
670	m->queue = PQ_NONE;
671
672	/* XXX before splx until vm_page_insert is safe */
673	vm_page_insert(m, object, pindex);
674
675	splx(s);
676
677	/*
678	 * Don't wakeup too often - wakeup the pageout daemon when
679	 * we would be nearly out of memory.
680	 */
681	if (((cnt.v_free_count + cnt.v_cache_count) <
682		(cnt.v_free_min + cnt.v_cache_min)) ||
683			(cnt.v_free_count < cnt.v_pageout_free_min))
684		pagedaemon_wakeup();
685
686	return (m);
687}
688
689vm_offset_t
690vm_page_alloc_contig(size, low, high, alignment)
691	vm_offset_t size;
692	vm_offset_t low;
693	vm_offset_t high;
694	vm_offset_t alignment;
695{
696	int i, s, start;
697	vm_offset_t addr, phys, tmp_addr;
698	vm_page_t pga = vm_page_array;
699
700	if ((alignment & (alignment - 1)) != 0)
701		panic("vm_page_alloc_contig: alignment must be a power of 2");
702
703	start = 0;
704	s = splhigh();
705again:
706	/*
707	 * Find first page in array that is free, within range, and aligned.
708	 */
709	for (i = start; i < cnt.v_page_count; i++) {
710		phys = VM_PAGE_TO_PHYS(&pga[i]);
711		if ((pga[i].queue == PQ_FREE) &&
712		    (phys >= low) && (phys < high) &&
713		    ((phys & (alignment - 1)) == 0))
714			break;
715	}
716
717	/*
718	 * If the above failed or we will exceed the upper bound, fail.
719	 */
720	if ((i == cnt.v_page_count) ||
721		((VM_PAGE_TO_PHYS(&pga[i]) + size) > high)) {
722		splx(s);
723		return (NULL);
724	}
725	start = i;
726
727	/*
728	 * Check successive pages for contiguous and free.
729	 */
730	for (i = start + 1; i < (start + size / PAGE_SIZE); i++) {
731		if ((VM_PAGE_TO_PHYS(&pga[i]) !=
732		    (VM_PAGE_TO_PHYS(&pga[i - 1]) + PAGE_SIZE)) ||
733		    (pga[i].queue != PQ_FREE)) {
734			start++;
735			goto again;
736		}
737	}
738
739	/*
740	 * We've found a contiguous chunk that meets are requirements.
741	 * Allocate kernel VM, unfree and assign the physical pages to it and
742	 * return kernel VM pointer.
743	 */
744	tmp_addr = addr = kmem_alloc_pageable(kernel_map, size);
745
746	for (i = start; i < (start + size / PAGE_SIZE); i++) {
747		vm_page_t m = &pga[i];
748
749		TAILQ_REMOVE(&vm_page_queue_free, m, pageq);
750		cnt.v_free_count--;
751		m->valid = VM_PAGE_BITS_ALL;
752		m->flags = 0;
753		m->dirty = 0;
754		m->wire_count = 0;
755		m->act_count = 0;
756		m->busy = 0;
757		m->queue = PQ_NONE;
758		vm_page_insert(m, kernel_object,
759			OFF_TO_IDX(tmp_addr - VM_MIN_KERNEL_ADDRESS));
760		vm_page_wire(m);
761		pmap_kenter(tmp_addr, VM_PAGE_TO_PHYS(m));
762		tmp_addr += PAGE_SIZE;
763	}
764
765	splx(s);
766	return (addr);
767}
768
769/*
770 *	vm_page_free:
771 *
772 *	Returns the given page to the free list,
773 *	disassociating it with any VM object.
774 *
775 *	Object and page must be locked prior to entry.
776 */
777void
778vm_page_free(m)
779	register vm_page_t m;
780{
781	int s;
782	int flags = m->flags;
783
784	s = splhigh();
785	if (m->busy || (flags & PG_BUSY) || (m->queue == PQ_FREE)) {
786		printf("vm_page_free: pindex(%ld), busy(%d), PG_BUSY(%d)\n",
787		    m->pindex, m->busy, (flags & PG_BUSY) ? 1 : 0);
788		if (m->queue == PQ_FREE)
789			panic("vm_page_free: freeing free page");
790		else
791			panic("vm_page_free: freeing busy page");
792	}
793
794	vm_page_remove(m);
795	vm_page_unqueue(m);
796
797/*
798	if ((flags & PG_WANTED) != 0)
799		wakeup(m);
800*/
801	if ((flags & PG_FICTITIOUS) == 0) {
802		if (m->wire_count) {
803			if (m->wire_count > 1) {
804				printf("vm_page_free: wire count > 1 (%d)", m->wire_count);
805				panic("vm_page_free: invalid wire count");
806			}
807			cnt.v_wire_count--;
808			m->wire_count = 0;
809		}
810		m->queue = PQ_FREE;
811		TAILQ_INSERT_TAIL(&vm_page_queue_free, m, pageq);
812		splx(s);
813		/*
814		 * if pageout daemon needs pages, then tell it that there are
815		 * some free.
816		 */
817		if (vm_pageout_pages_needed) {
818			wakeup(&vm_pageout_pages_needed);
819			vm_pageout_pages_needed = 0;
820		}
821
822		cnt.v_free_count++;
823		/*
824		 * wakeup processes that are waiting on memory if we hit a
825		 * high water mark. And wakeup scheduler process if we have
826		 * lots of memory. this process will swapin processes.
827		 */
828		if ((cnt.v_free_count + cnt.v_cache_count) == cnt.v_free_min) {
829			wakeup(&cnt.v_free_count);
830			wakeup(&proc0);
831		}
832	} else {
833		splx(s);
834	}
835	cnt.v_tfree++;
836}
837
838
839/*
840 *	vm_page_wire:
841 *
842 *	Mark this page as wired down by yet
843 *	another map, removing it from paging queues
844 *	as necessary.
845 *
846 *	The page queues must be locked.
847 */
848void
849vm_page_wire(m)
850	register vm_page_t m;
851{
852	int s;
853
854	if (m->wire_count == 0) {
855		s = splhigh();
856		vm_page_unqueue(m);
857		splx(s);
858		cnt.v_wire_count++;
859	}
860	m->wire_count++;
861	m->flags |= PG_MAPPED;
862}
863
864/*
865 *	vm_page_unwire:
866 *
867 *	Release one wiring of this page, potentially
868 *	enabling it to be paged again.
869 *
870 *	The page queues must be locked.
871 */
872void
873vm_page_unwire(m)
874	register vm_page_t m;
875{
876	int s;
877
878	s = splhigh();
879
880	if (m->wire_count > 0)
881		m->wire_count--;
882
883	if (m->wire_count == 0) {
884		cnt.v_wire_count--;
885		TAILQ_INSERT_TAIL(&vm_page_queue_active, m, pageq);
886		m->queue = PQ_ACTIVE;
887		if( m->act_count < ACT_MAX)
888			m->act_count += 1;
889		cnt.v_active_count++;
890	}
891	splx(s);
892}
893
894/*
895 *	vm_page_activate:
896 *
897 *	Put the specified page on the active list (if appropriate).
898 *
899 *	The page queues must be locked.
900 */
901void
902vm_page_activate(m)
903	register vm_page_t m;
904{
905	int s;
906
907	s = splhigh();
908	if (m->queue == PQ_ACTIVE)
909		panic("vm_page_activate: already active");
910
911	if (m->queue == PQ_CACHE)
912		cnt.v_reactivated++;
913
914	vm_page_unqueue(m);
915
916	if (m->wire_count == 0) {
917		TAILQ_INSERT_TAIL(&vm_page_queue_active, m, pageq);
918		m->queue = PQ_ACTIVE;
919		if (m->act_count < 5)
920			m->act_count = 5;
921		else if( m->act_count < ACT_MAX)
922			m->act_count += 1;
923		cnt.v_active_count++;
924	}
925	splx(s);
926}
927
928/*
929 *	vm_page_deactivate:
930 *
931 *	Returns the given page to the inactive list,
932 *	indicating that no physical maps have access
933 *	to this page.  [Used by the physical mapping system.]
934 *
935 *	The page queues must be locked.
936 */
937void
938vm_page_deactivate(m)
939	register vm_page_t m;
940{
941	int spl;
942
943	/*
944	 * Only move active pages -- ignore locked or already inactive ones.
945	 *
946	 * XXX: sometimes we get pages which aren't wired down or on any queue -
947	 * we need to put them on the inactive queue also, otherwise we lose
948	 * track of them. Paul Mackerras (paulus@cs.anu.edu.au) 9-Jan-93.
949	 */
950	if (m->queue == PQ_INACTIVE)
951		return;
952
953	spl = splhigh();
954	if (m->wire_count == 0 && m->hold_count == 0) {
955		if (m->queue == PQ_CACHE)
956			cnt.v_reactivated++;
957		vm_page_unqueue(m);
958		TAILQ_INSERT_TAIL(&vm_page_queue_inactive, m, pageq);
959		m->queue = PQ_INACTIVE;
960		cnt.v_inactive_count++;
961		m->act_count = 0;
962	}
963	splx(spl);
964}
965
966/*
967 * vm_page_cache
968 *
969 * Put the specified page onto the page cache queue (if appropriate).
970 */
971void
972vm_page_cache(m)
973	register vm_page_t m;
974{
975	int s;
976
977	if ((m->flags & PG_BUSY) || m->busy || m->wire_count)
978		return;
979	if (m->queue == PQ_CACHE)
980		return;
981
982	vm_page_protect(m, VM_PROT_NONE);
983	s = splhigh();
984	vm_page_unqueue(m);
985	TAILQ_INSERT_TAIL(&vm_page_queue_cache, m, pageq);
986	m->queue = PQ_CACHE;
987	cnt.v_cache_count++;
988	if ((cnt.v_free_count + cnt.v_cache_count) == cnt.v_free_min) {
989		wakeup(&cnt.v_free_count);
990		wakeup(&proc0);
991	}
992	if (vm_pageout_pages_needed) {
993		wakeup(&vm_pageout_pages_needed);
994		vm_pageout_pages_needed = 0;
995	}
996	splx(s);
997}
998
999/*
1000 *	vm_page_zero_fill:
1001 *
1002 *	Zero-fill the specified page.
1003 *	Written as a standard pagein routine, to
1004 *	be used by the zero-fill object.
1005 */
1006boolean_t
1007vm_page_zero_fill(m)
1008	vm_page_t m;
1009{
1010	pmap_zero_page(VM_PAGE_TO_PHYS(m));
1011	return (TRUE);
1012}
1013
1014/*
1015 *	vm_page_copy:
1016 *
1017 *	Copy one page to another
1018 */
1019void
1020vm_page_copy(src_m, dest_m)
1021	vm_page_t src_m;
1022	vm_page_t dest_m;
1023{
1024	pmap_copy_page(VM_PAGE_TO_PHYS(src_m), VM_PAGE_TO_PHYS(dest_m));
1025	dest_m->valid = VM_PAGE_BITS_ALL;
1026}
1027
1028
1029/*
1030 * mapping function for valid bits or for dirty bits in
1031 * a page
1032 */
1033inline int
1034vm_page_bits(int base, int size)
1035{
1036	u_short chunk;
1037
1038	if ((base == 0) && (size >= PAGE_SIZE))
1039		return VM_PAGE_BITS_ALL;
1040	size = (size + DEV_BSIZE - 1) & ~(DEV_BSIZE - 1);
1041	base = (base % PAGE_SIZE) / DEV_BSIZE;
1042	chunk = vm_page_dev_bsize_chunks[size / DEV_BSIZE];
1043	return (chunk << base) & VM_PAGE_BITS_ALL;
1044}
1045
1046/*
1047 * set a page valid and clean
1048 */
1049void
1050vm_page_set_validclean(m, base, size)
1051	vm_page_t m;
1052	int base;
1053	int size;
1054{
1055	int pagebits = vm_page_bits(base, size);
1056	m->valid |= pagebits;
1057	m->dirty &= ~pagebits;
1058	if( base == 0 && size == PAGE_SIZE)
1059		pmap_clear_modify(VM_PAGE_TO_PHYS(m));
1060}
1061
1062/*
1063 * set a page (partially) invalid
1064 */
1065void
1066vm_page_set_invalid(m, base, size)
1067	vm_page_t m;
1068	int base;
1069	int size;
1070{
1071	int bits;
1072
1073	m->valid &= ~(bits = vm_page_bits(base, size));
1074	if (m->valid == 0)
1075		m->dirty &= ~bits;
1076}
1077
1078/*
1079 * is (partial) page valid?
1080 */
1081int
1082vm_page_is_valid(m, base, size)
1083	vm_page_t m;
1084	int base;
1085	int size;
1086{
1087	int bits = vm_page_bits(base, size);
1088
1089	if (m->valid && ((m->valid & bits) == bits))
1090		return 1;
1091	else
1092		return 0;
1093}
1094
1095
1096
1097void
1098vm_page_test_dirty(m)
1099	vm_page_t m;
1100{
1101	if ((m->dirty != VM_PAGE_BITS_ALL) &&
1102	    pmap_is_modified(VM_PAGE_TO_PHYS(m))) {
1103		m->dirty = VM_PAGE_BITS_ALL;
1104	}
1105}
1106
1107#ifdef DDB
1108void
1109DDB_print_page_info(void)
1110{
1111	printf("cnt.v_free_count: %d\n", cnt.v_free_count);
1112	printf("cnt.v_cache_count: %d\n", cnt.v_cache_count);
1113	printf("cnt.v_inactive_count: %d\n", cnt.v_inactive_count);
1114	printf("cnt.v_active_count: %d\n", cnt.v_active_count);
1115	printf("cnt.v_wire_count: %d\n", cnt.v_wire_count);
1116	printf("cnt.v_free_reserved: %d\n", cnt.v_free_reserved);
1117	printf("cnt.v_free_min: %d\n", cnt.v_free_min);
1118	printf("cnt.v_free_target: %d\n", cnt.v_free_target);
1119	printf("cnt.v_cache_min: %d\n", cnt.v_cache_min);
1120	printf("cnt.v_inactive_target: %d\n", cnt.v_inactive_target);
1121}
1122#endif
1123