vm_page.c revision 32702
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.86 1998/01/17 09:16:59 dyson 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
71#include <sys/param.h>
72#include <sys/systm.h>
73#include <sys/malloc.h>
74#include <sys/proc.h>
75#include <sys/vmmeter.h>
76#include <sys/vnode.h>
77
78#include <vm/vm.h>
79#include <vm/vm_param.h>
80#include <vm/vm_prot.h>
81#include <sys/lock.h>
82#include <vm/vm_kern.h>
83#include <vm/vm_object.h>
84#include <vm/vm_page.h>
85#include <vm/vm_pageout.h>
86#include <vm/vm_extern.h>
87
88static void	vm_page_queue_init __P((void));
89static vm_page_t vm_page_select_free __P((vm_object_t object,
90			vm_pindex_t pindex, int prefqueue));
91
92/*
93 *	Associated with page of user-allocatable memory is a
94 *	page structure.
95 */
96
97static int vm_page_bucket_generation;	/* generation id for buckets */
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[PQ_L2_SIZE] = {0};
103struct pglist vm_page_queue_zero[PQ_L2_SIZE] = {0};
104struct pglist vm_page_queue_active = {0};
105struct pglist vm_page_queue_inactive = {0};
106struct pglist vm_page_queue_cache[PQ_L2_SIZE] = {0};
107
108int no_queue=0;
109
110struct vpgqueues vm_page_queues[PQ_COUNT] = {0};
111int pqcnt[PQ_COUNT] = {0};
112
113static void
114vm_page_queue_init(void) {
115	int i;
116
117	vm_page_queues[PQ_NONE].pl = NULL;
118	vm_page_queues[PQ_NONE].cnt = &no_queue;
119	for(i=0;i<PQ_L2_SIZE;i++) {
120		vm_page_queues[PQ_FREE+i].pl = &vm_page_queue_free[i];
121		vm_page_queues[PQ_FREE+i].cnt = &cnt.v_free_count;
122	}
123	for(i=0;i<PQ_L2_SIZE;i++) {
124		vm_page_queues[PQ_ZERO+i].pl = &vm_page_queue_zero[i];
125		vm_page_queues[PQ_ZERO+i].cnt = &cnt.v_free_count;
126	}
127	vm_page_queues[PQ_INACTIVE].pl = &vm_page_queue_inactive;
128	vm_page_queues[PQ_INACTIVE].cnt = &cnt.v_inactive_count;
129
130	vm_page_queues[PQ_ACTIVE].pl = &vm_page_queue_active;
131	vm_page_queues[PQ_ACTIVE].cnt = &cnt.v_active_count;
132	for(i=0;i<PQ_L2_SIZE;i++) {
133		vm_page_queues[PQ_CACHE+i].pl = &vm_page_queue_cache[i];
134		vm_page_queues[PQ_CACHE+i].cnt = &cnt.v_cache_count;
135	}
136	for(i=0;i<PQ_COUNT;i++) {
137		if (vm_page_queues[i].pl) {
138			TAILQ_INIT(vm_page_queues[i].pl);
139		} else if (i != 0) {
140			panic("vm_page_queue_init: queue %d is null", i);
141		}
142		vm_page_queues[i].lcnt = &pqcnt[i];
143	}
144}
145
146vm_page_t vm_page_array = 0;
147int vm_page_array_size = 0;
148long first_page = 0;
149static long last_page;
150static vm_size_t page_mask;
151static int page_shift;
152int vm_page_zero_count = 0;
153
154/*
155 * map of contiguous valid DEV_BSIZE chunks in a page
156 * (this list is valid for page sizes upto 16*DEV_BSIZE)
157 */
158static u_short vm_page_dev_bsize_chunks[] = {
159	0x0, 0x1, 0x3, 0x7, 0xf, 0x1f, 0x3f, 0x7f, 0xff,
160	0x1ff, 0x3ff, 0x7ff, 0xfff, 0x1fff, 0x3fff, 0x7fff, 0xffff
161};
162
163static inline int vm_page_hash __P((vm_object_t object, vm_pindex_t pindex));
164static int vm_page_freechk_and_unqueue __P((vm_page_t m));
165static void vm_page_free_wakeup __P((void));
166
167/*
168 *	vm_set_page_size:
169 *
170 *	Sets the page size, perhaps based upon the memory
171 *	size.  Must be called before any use of page-size
172 *	dependent functions.
173 *
174 *	Sets page_shift and page_mask from cnt.v_page_size.
175 */
176void
177vm_set_page_size()
178{
179
180	if (cnt.v_page_size == 0)
181		cnt.v_page_size = DEFAULT_PAGE_SIZE;
182	page_mask = cnt.v_page_size - 1;
183	if ((page_mask & cnt.v_page_size) != 0)
184		panic("vm_set_page_size: page size not a power of two");
185	for (page_shift = 0;; page_shift++)
186		if ((1 << page_shift) == cnt.v_page_size)
187			break;
188}
189
190/*
191 *	vm_page_startup:
192 *
193 *	Initializes the resident memory module.
194 *
195 *	Allocates memory for the page cells, and
196 *	for the object/offset-to-page hash table headers.
197 *	Each page cell is initialized and placed on the free list.
198 */
199
200vm_offset_t
201vm_page_startup(starta, enda, vaddr)
202	register vm_offset_t starta;
203	vm_offset_t enda;
204	register vm_offset_t vaddr;
205{
206	register vm_offset_t mapped;
207	register vm_page_t m;
208	register struct pglist *bucket;
209	vm_size_t npages, page_range;
210	register vm_offset_t new_start;
211	int i;
212	vm_offset_t pa;
213	int nblocks;
214	vm_offset_t first_managed_page;
215
216	/* the biggest memory array is the second group of pages */
217	vm_offset_t start;
218	vm_offset_t biggestone, biggestsize;
219
220	vm_offset_t total;
221
222	total = 0;
223	biggestsize = 0;
224	biggestone = 0;
225	nblocks = 0;
226	vaddr = round_page(vaddr);
227
228	for (i = 0; phys_avail[i + 1]; i += 2) {
229		phys_avail[i] = round_page(phys_avail[i]);
230		phys_avail[i + 1] = trunc_page(phys_avail[i + 1]);
231	}
232
233	for (i = 0; phys_avail[i + 1]; i += 2) {
234		int size = phys_avail[i + 1] - phys_avail[i];
235
236		if (size > biggestsize) {
237			biggestone = i;
238			biggestsize = size;
239		}
240		++nblocks;
241		total += size;
242	}
243
244	start = phys_avail[biggestone];
245
246	/*
247	 * Initialize the queue headers for the free queue, the active queue
248	 * and the inactive queue.
249	 */
250
251	vm_page_queue_init();
252
253	/*
254	 * Allocate (and initialize) the hash table buckets.
255	 *
256	 * The number of buckets MUST BE a power of 2, and the actual value is
257	 * the next power of 2 greater than the number of physical pages in
258	 * the system.
259	 *
260	 * Note: This computation can be tweaked if desired.
261	 */
262	vm_page_buckets = (struct pglist *) vaddr;
263	bucket = vm_page_buckets;
264	if (vm_page_bucket_count == 0) {
265		vm_page_bucket_count = 1;
266		while (vm_page_bucket_count < atop(total))
267			vm_page_bucket_count <<= 1;
268	}
269	vm_page_hash_mask = vm_page_bucket_count - 1;
270
271	/*
272	 * Validate these addresses.
273	 */
274
275	new_start = start + vm_page_bucket_count * sizeof(struct pglist);
276	new_start = round_page(new_start);
277	mapped = vaddr;
278	vaddr = pmap_map(mapped, start, new_start,
279	    VM_PROT_READ | VM_PROT_WRITE);
280	start = new_start;
281	bzero((caddr_t) mapped, vaddr - mapped);
282	mapped = vaddr;
283
284	for (i = 0; i < vm_page_bucket_count; i++) {
285		TAILQ_INIT(bucket);
286		bucket++;
287	}
288
289	/*
290	 * Validate these zone addresses.
291	 */
292
293	new_start = start + (vaddr - mapped);
294	pmap_map(mapped, start, new_start, VM_PROT_READ | VM_PROT_WRITE);
295	bzero((caddr_t) mapped, (vaddr - mapped));
296	start = round_page(new_start);
297
298	/*
299	 * Compute the number of pages of memory that will be available for
300	 * use (taking into account the overhead of a page structure per
301	 * page).
302	 */
303
304	first_page = phys_avail[0] / PAGE_SIZE;
305	last_page = phys_avail[(nblocks - 1) * 2 + 1] / PAGE_SIZE;
306
307	page_range = last_page - (phys_avail[0] / PAGE_SIZE);
308	npages = (total - (page_range * sizeof(struct vm_page)) -
309	    (start - phys_avail[biggestone])) / PAGE_SIZE;
310
311	/*
312	 * Initialize the mem entry structures now, and put them in the free
313	 * queue.
314	 */
315
316	vm_page_array = (vm_page_t) vaddr;
317	mapped = vaddr;
318
319	/*
320	 * Validate these addresses.
321	 */
322
323	new_start = round_page(start + page_range * sizeof(struct vm_page));
324	mapped = pmap_map(mapped, start, new_start,
325	    VM_PROT_READ | VM_PROT_WRITE);
326	start = new_start;
327
328	first_managed_page = start / PAGE_SIZE;
329
330	/*
331	 * Clear all of the page structures
332	 */
333	bzero((caddr_t) vm_page_array, page_range * sizeof(struct vm_page));
334	vm_page_array_size = page_range;
335
336	cnt.v_page_count = 0;
337	cnt.v_free_count = 0;
338	for (i = 0; phys_avail[i + 1] && npages > 0; i += 2) {
339		if (i == biggestone)
340			pa = ptoa(first_managed_page);
341		else
342			pa = phys_avail[i];
343		while (pa < phys_avail[i + 1] && npages-- > 0) {
344			++cnt.v_page_count;
345			++cnt.v_free_count;
346			m = PHYS_TO_VM_PAGE(pa);
347			m->phys_addr = pa;
348			m->flags = 0;
349			m->pc = (pa >> PAGE_SHIFT) & PQ_L2_MASK;
350			m->queue = PQ_FREE + m->pc;
351			TAILQ_INSERT_TAIL(vm_page_queues[m->queue].pl, m, pageq);
352			++(*vm_page_queues[m->queue].lcnt);
353			pa += PAGE_SIZE;
354		}
355	}
356
357	return (mapped);
358}
359
360/*
361 *	vm_page_hash:
362 *
363 *	Distributes the object/offset key pair among hash buckets.
364 *
365 *	NOTE:  This macro depends on vm_page_bucket_count being a power of 2.
366 */
367static inline int
368vm_page_hash(object, pindex)
369	vm_object_t object;
370	vm_pindex_t pindex;
371{
372	return ((((unsigned) object) >> 5) + (pindex >> 1)) & vm_page_hash_mask;
373}
374
375/*
376 *	vm_page_insert:		[ internal use only ]
377 *
378 *	Inserts the given mem entry into the object/object-page
379 *	table and object list.
380 *
381 *	The object and page must be locked, and must be splhigh.
382 */
383
384void
385vm_page_insert(m, object, pindex)
386	register vm_page_t m;
387	register vm_object_t object;
388	register vm_pindex_t pindex;
389{
390	register struct pglist *bucket;
391
392	if (m->flags & PG_TABLED)
393		panic("vm_page_insert: already inserted");
394
395	/*
396	 * Record the object/offset pair in this page
397	 */
398
399	m->object = object;
400	m->pindex = pindex;
401
402	/*
403	 * Insert it into the object_object/offset hash table
404	 */
405
406	bucket = &vm_page_buckets[vm_page_hash(object, pindex)];
407	TAILQ_INSERT_TAIL(bucket, m, hashq);
408	vm_page_bucket_generation++;
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	m->object->page_hint = m;
417	m->object->generation++;
418
419	/*
420	 * And show that the object has one more resident page.
421	 */
422
423	object->resident_page_count++;
424}
425
426/*
427 *	vm_page_remove:		[ internal use only ]
428 *				NOTE: used by device pager as well -wfj
429 *
430 *	Removes the given mem entry from the object/offset-page
431 *	table and the object page list.
432 *
433 *	The object and page must be locked, and at splhigh.
434 */
435
436void
437vm_page_remove(m)
438	register vm_page_t m;
439{
440	register struct pglist *bucket;
441
442	if (!(m->flags & PG_TABLED))
443		return;
444
445	if (m->object->page_hint == m)
446		m->object->page_hint = NULL;
447
448	/*
449	 * Remove from the object_object/offset hash table
450	 */
451
452	bucket = &vm_page_buckets[vm_page_hash(m->object, m->pindex)];
453	TAILQ_REMOVE(bucket, m, hashq);
454	vm_page_bucket_generation++;
455
456	/*
457	 * Now remove from the object's list of backed pages.
458	 */
459
460	TAILQ_REMOVE(&m->object->memq, m, listq);
461
462	/*
463	 * And show that the object has one fewer resident page.
464	 */
465
466	m->object->resident_page_count--;
467	m->object->generation++;
468
469	m->flags &= ~PG_TABLED;
470}
471
472/*
473 *	vm_page_lookup:
474 *
475 *	Returns the page associated with the object/offset
476 *	pair specified; if none is found, NULL is returned.
477 *
478 *	The object must be locked.  No side effects.
479 */
480
481vm_page_t
482vm_page_lookup(object, pindex)
483	register vm_object_t object;
484	register vm_pindex_t pindex;
485{
486	register vm_page_t m;
487	register struct pglist *bucket;
488	int curgeneration;
489	int s;
490
491	/*
492	 * Search the hash table for this object/offset pair
493	 */
494
495	bucket = &vm_page_buckets[vm_page_hash(object, pindex)];
496
497restart:
498	curgeneration = vm_page_bucket_generation;
499	for (m = TAILQ_FIRST(bucket); m != NULL; m = TAILQ_NEXT(m,hashq)) {
500		if (curgeneration != vm_page_bucket_generation)
501			goto restart;
502		if ((m->object == object) && (m->pindex == pindex)) {
503			m->object->page_hint = m;
504			return (m);
505		}
506	}
507	return (NULL);
508}
509
510/*
511 *	vm_page_rename:
512 *
513 *	Move the given memory entry from its
514 *	current object to the specified target object/offset.
515 *
516 *	The object must be locked.
517 */
518void
519vm_page_rename(m, new_object, new_pindex)
520	register vm_page_t m;
521	register vm_object_t new_object;
522	vm_pindex_t new_pindex;
523{
524	int s;
525
526	s = splvm();
527	vm_page_remove(m);
528	vm_page_insert(m, new_object, new_pindex);
529	splx(s);
530}
531
532/*
533 * vm_page_unqueue without any wakeup
534 */
535void
536vm_page_unqueue_nowakeup(m)
537	vm_page_t m;
538{
539	int queue = m->queue;
540	struct vpgqueues *pq;
541	if (queue != PQ_NONE) {
542		pq = &vm_page_queues[queue];
543		m->queue = PQ_NONE;
544		TAILQ_REMOVE(pq->pl, m, pageq);
545		--(*pq->cnt);
546		--(*pq->lcnt);
547	}
548}
549
550/*
551 * vm_page_unqueue must be called at splhigh();
552 */
553void
554vm_page_unqueue(m)
555	vm_page_t m;
556{
557	int queue = m->queue;
558	struct vpgqueues *pq;
559	if (queue != PQ_NONE) {
560		m->queue = PQ_NONE;
561		pq = &vm_page_queues[queue];
562		TAILQ_REMOVE(pq->pl, m, pageq);
563		--(*pq->cnt);
564		--(*pq->lcnt);
565		if ((queue - m->pc) == PQ_CACHE) {
566			if ((cnt.v_cache_count + cnt.v_free_count) <
567				(cnt.v_free_reserved + cnt.v_cache_min))
568				pagedaemon_wakeup();
569		}
570	}
571}
572
573/*
574 * Find a page on the specified queue with color optimization.
575 */
576vm_page_t
577vm_page_list_find(basequeue, index)
578	int basequeue, index;
579{
580#if PQ_L2_SIZE > 1
581
582	int i,j;
583	vm_page_t m;
584	int hindex;
585	struct vpgqueues *pq;
586
587	pq = &vm_page_queues[basequeue];
588
589	m = TAILQ_FIRST(pq[index].pl);
590	if (m)
591		return m;
592
593	for(j = 0; j < PQ_L1_SIZE; j++) {
594		int ij;
595		for(i = (PQ_L2_SIZE / 2) - PQ_L1_SIZE;
596			(ij = i + j) > 0;
597			i -= PQ_L1_SIZE) {
598
599			hindex = index + ij;
600			if (hindex >= PQ_L2_SIZE)
601				hindex -= PQ_L2_SIZE;
602			if (m = TAILQ_FIRST(pq[hindex].pl))
603				return m;
604
605			hindex = index - ij;
606			if (hindex < 0)
607				hindex += PQ_L2_SIZE;
608			if (m = TAILQ_FIRST(pq[hindex].pl))
609				return m;
610		}
611	}
612
613	hindex = index + PQ_L2_SIZE / 2;
614	if (hindex >= PQ_L2_SIZE)
615		hindex -= PQ_L2_SIZE;
616	m = TAILQ_FIRST(pq[hindex].pl);
617	if (m)
618		return m;
619
620	return NULL;
621#else
622	return TAILQ_FIRST(vm_page_queues[basequeue].pl);
623#endif
624
625}
626
627/*
628 * Find a page on the specified queue with color optimization.
629 */
630vm_page_t
631vm_page_select(object, pindex, basequeue)
632	vm_object_t object;
633	vm_pindex_t pindex;
634	int basequeue;
635{
636
637#if PQ_L2_SIZE > 1
638	int index;
639	index = (pindex + object->pg_color) & PQ_L2_MASK;
640	return vm_page_list_find(basequeue, index);
641
642#else
643	return TAILQ_FIRST(vm_page_queues[basequeue].pl);
644#endif
645
646}
647
648/*
649 * Find a free or zero page, with specified preference.
650 */
651static vm_page_t
652vm_page_select_free(object, pindex, prefqueue)
653	vm_object_t object;
654	vm_pindex_t pindex;
655	int prefqueue;
656{
657#if PQ_L2_SIZE > 1
658	int i,j;
659	int index, hindex;
660#endif
661	vm_page_t m, mh;
662	int oqueuediff;
663	struct vpgqueues *pq;
664
665	if (prefqueue == PQ_ZERO)
666		oqueuediff = PQ_FREE - PQ_ZERO;
667	else
668		oqueuediff = PQ_ZERO - PQ_FREE;
669
670	if (mh = object->page_hint) {
671		 if (mh->pindex == (pindex - 1)) {
672			if ((mh->flags & PG_FICTITIOUS) == 0) {
673				if ((mh < &vm_page_array[cnt.v_page_count-1]) &&
674					(mh >= &vm_page_array[0])) {
675					int queue;
676					m = mh + 1;
677					if (VM_PAGE_TO_PHYS(m) == (VM_PAGE_TO_PHYS(mh) + PAGE_SIZE)) {
678						queue = m->queue - m->pc;
679						if (queue == PQ_FREE || queue == PQ_ZERO) {
680							return m;
681						}
682					}
683				}
684			}
685		}
686	}
687
688	pq = &vm_page_queues[prefqueue];
689
690#if PQ_L2_SIZE > 1
691
692	index = (pindex + object->pg_color) & PQ_L2_MASK;
693
694	if (m = TAILQ_FIRST(pq[index].pl))
695		return m;
696	if (m = TAILQ_FIRST(pq[index + oqueuediff].pl))
697		return m;
698
699	for(j = 0; j < PQ_L1_SIZE; j++) {
700		int ij;
701		for(i = (PQ_L2_SIZE / 2) - PQ_L1_SIZE;
702			(ij = i + j) >= 0;
703			i -= PQ_L1_SIZE) {
704
705			hindex = index + ij;
706			if (hindex >= PQ_L2_SIZE)
707				hindex -= PQ_L2_SIZE;
708			if (m = TAILQ_FIRST(pq[hindex].pl))
709				return m;
710			if (m = TAILQ_FIRST(pq[hindex + oqueuediff].pl))
711				return m;
712
713			hindex = index - ij;
714			if (hindex < 0)
715				hindex += PQ_L2_SIZE;
716			if (m = TAILQ_FIRST(pq[hindex].pl))
717				return m;
718			if (m = TAILQ_FIRST(pq[hindex + oqueuediff].pl))
719				return m;
720		}
721	}
722
723	hindex = index + PQ_L2_SIZE / 2;
724	if (hindex >= PQ_L2_SIZE)
725		hindex -= PQ_L2_SIZE;
726	if (m = TAILQ_FIRST(pq[hindex].pl))
727		return m;
728	if (m = TAILQ_FIRST(pq[hindex+oqueuediff].pl))
729		return m;
730
731#else
732	if (m = TAILQ_FIRST(pq[0].pl))
733		return m;
734	else
735		return TAILQ_FIRST(pq[oqueuediff].pl);
736#endif
737
738	return NULL;
739}
740
741/*
742 *	vm_page_alloc:
743 *
744 *	Allocate and return a memory cell associated
745 *	with this VM object/offset pair.
746 *
747 *	page_req classes:
748 *	VM_ALLOC_NORMAL		normal process request
749 *	VM_ALLOC_SYSTEM		system *really* needs a page
750 *	VM_ALLOC_INTERRUPT	interrupt time request
751 *	VM_ALLOC_ZERO		zero page
752 *
753 *	Object must be locked.
754 */
755vm_page_t
756vm_page_alloc(object, pindex, page_req)
757	vm_object_t object;
758	vm_pindex_t pindex;
759	int page_req;
760{
761	register vm_page_t m;
762	struct vpgqueues *pq;
763	vm_object_t oldobject;
764	int queue, qtype;
765	int s;
766
767#ifdef DIAGNOSTIC
768	m = vm_page_lookup(object, pindex);
769	if (m)
770		panic("vm_page_alloc: page already allocated");
771#endif
772
773	if ((curproc == pageproc) && (page_req != VM_ALLOC_INTERRUPT)) {
774		page_req = VM_ALLOC_SYSTEM;
775	};
776
777	s = splvm();
778
779	switch (page_req) {
780
781	case VM_ALLOC_NORMAL:
782		if (cnt.v_free_count >= cnt.v_free_reserved) {
783			m = vm_page_select_free(object, pindex, PQ_FREE);
784#if defined(DIAGNOSTIC)
785			if (m == NULL)
786				panic("vm_page_alloc(NORMAL): missing page on free queue\n");
787#endif
788		} else {
789			m = vm_page_select(object, pindex, PQ_CACHE);
790			if (m == NULL) {
791				splx(s);
792#if defined(DIAGNOSTIC)
793				if (cnt.v_cache_count > 0)
794					printf("vm_page_alloc(NORMAL): missing pages on cache queue: %d\n", cnt.v_cache_count);
795#endif
796				vm_pageout_deficit++;
797				pagedaemon_wakeup();
798				return (NULL);
799			}
800		}
801		break;
802
803	case VM_ALLOC_ZERO:
804		if (cnt.v_free_count >= cnt.v_free_reserved) {
805			m = vm_page_select_free(object, pindex, PQ_ZERO);
806#if defined(DIAGNOSTIC)
807			if (m == NULL)
808				panic("vm_page_alloc(ZERO): missing page on free queue\n");
809#endif
810		} else {
811			m = vm_page_select(object, pindex, PQ_CACHE);
812			if (m == NULL) {
813				splx(s);
814#if defined(DIAGNOSTIC)
815				if (cnt.v_cache_count > 0)
816					printf("vm_page_alloc(ZERO): missing pages on cache queue: %d\n", cnt.v_cache_count);
817#endif
818				vm_pageout_deficit++;
819				pagedaemon_wakeup();
820				return (NULL);
821			}
822		}
823		break;
824
825	case VM_ALLOC_SYSTEM:
826		if ((cnt.v_free_count >= cnt.v_free_reserved) ||
827		    ((cnt.v_cache_count == 0) &&
828		    (cnt.v_free_count >= cnt.v_interrupt_free_min))) {
829			m = vm_page_select_free(object, pindex, PQ_FREE);
830#if defined(DIAGNOSTIC)
831			if (m == NULL)
832				panic("vm_page_alloc(SYSTEM): missing page on free queue\n");
833#endif
834		} else {
835			m = vm_page_select(object, pindex, PQ_CACHE);
836			if (m == NULL) {
837				splx(s);
838#if defined(DIAGNOSTIC)
839				if (cnt.v_cache_count > 0)
840					printf("vm_page_alloc(SYSTEM): missing pages on cache queue: %d\n", cnt.v_cache_count);
841#endif
842				vm_pageout_deficit++;
843				pagedaemon_wakeup();
844				return (NULL);
845			}
846		}
847		break;
848
849	case VM_ALLOC_INTERRUPT:
850		if (cnt.v_free_count > 0) {
851			m = vm_page_select_free(object, pindex, PQ_FREE);
852#if defined(DIAGNOSTIC)
853			if (m == NULL)
854				panic("vm_page_alloc(INTERRUPT): missing page on free queue\n");
855#endif
856		} else {
857			splx(s);
858			vm_pageout_deficit++;
859			pagedaemon_wakeup();
860			return (NULL);
861		}
862		break;
863
864	default:
865		panic("vm_page_alloc: invalid allocation class");
866	}
867
868	queue = m->queue;
869	qtype = queue - m->pc;
870	if (qtype == PQ_ZERO)
871		--vm_page_zero_count;
872	pq = &vm_page_queues[queue];
873	TAILQ_REMOVE(pq->pl, m, pageq);
874	--(*pq->cnt);
875	--(*pq->lcnt);
876	oldobject = NULL;
877	if (qtype == PQ_ZERO) {
878		m->flags = PG_ZERO|PG_BUSY;
879	} else if (qtype == PQ_CACHE) {
880		oldobject = m->object;
881		vm_page_remove(m);
882		m->flags = PG_BUSY;
883	} else {
884		m->flags = PG_BUSY;
885	}
886	m->wire_count = 0;
887	m->hold_count = 0;
888	m->act_count = 0;
889	m->busy = 0;
890	m->valid = 0;
891	m->dirty = 0;
892	m->queue = PQ_NONE;
893
894	/* XXX before splx until vm_page_insert is safe */
895	vm_page_insert(m, object, pindex);
896
897	/*
898	 * Don't wakeup too often - wakeup the pageout daemon when
899	 * we would be nearly out of memory.
900	 */
901	if (((cnt.v_free_count + cnt.v_cache_count) <
902		(cnt.v_free_reserved + cnt.v_cache_min)) ||
903			(cnt.v_free_count < cnt.v_pageout_free_min))
904		pagedaemon_wakeup();
905
906	if ((qtype == PQ_CACHE) &&
907		((page_req == VM_ALLOC_NORMAL) || (page_req == VM_ALLOC_ZERO)) &&
908		oldobject && (oldobject->type == OBJT_VNODE) &&
909		((oldobject->flags & OBJ_DEAD) == 0)) {
910		struct vnode *vp;
911		vp = (struct vnode *) oldobject->handle;
912		if (vp && VSHOULDFREE(vp)) {
913			if ((vp->v_flag & (VFREE|VTBFREE|VDOOMED)) == 0) {
914				TAILQ_INSERT_TAIL(&vnode_tobefree_list, vp, v_freelist);
915				vp->v_flag |= VTBFREE;
916			}
917		}
918	}
919	splx(s);
920
921	return (m);
922}
923
924void
925vm_wait()
926{
927	int s;
928
929	s = splvm();
930	if (curproc == pageproc) {
931		vm_pageout_pages_needed = 1;
932		tsleep(&vm_pageout_pages_needed, PSWP, "vmwait", 0);
933	} else {
934		if (!vm_pages_needed) {
935			vm_pages_needed++;
936			wakeup(&vm_pages_needed);
937		}
938		tsleep(&cnt.v_free_count, PVM, "vmwait", 0);
939	}
940	splx(s);
941}
942
943
944/*
945 *	vm_page_activate:
946 *
947 *	Put the specified page on the active list (if appropriate).
948 *
949 *	The page queues must be locked.
950 */
951void
952vm_page_activate(m)
953	register vm_page_t m;
954{
955	int s;
956
957	s = splvm();
958	if (m->queue == PQ_ACTIVE)
959		panic("vm_page_activate: already active");
960
961	if ((m->queue - m->pc) == PQ_CACHE)
962		cnt.v_reactivated++;
963
964	vm_page_unqueue(m);
965
966	if (m->wire_count == 0) {
967		m->queue = PQ_ACTIVE;
968		++(*vm_page_queues[PQ_ACTIVE].lcnt);
969		TAILQ_INSERT_TAIL(&vm_page_queue_active, m, pageq);
970		if (m->act_count < ACT_INIT)
971			m->act_count = ACT_INIT;
972		cnt.v_active_count++;
973	}
974	splx(s);
975}
976
977/*
978 * helper routine for vm_page_free and vm_page_free_zero
979 */
980static int
981vm_page_freechk_and_unqueue(m)
982	vm_page_t m;
983{
984	vm_object_t oldobject;
985
986	oldobject = m->object;
987
988#if !defined(MAX_PERF)
989	if (m->busy ||
990		(m->flags & PG_BUSY) ||
991		((m->queue - m->pc) == PQ_FREE) ||
992		(m->hold_count != 0)) {
993		printf("vm_page_free: pindex(%ld), busy(%d), PG_BUSY(%d), hold(%d)\n",
994			m->pindex, m->busy,
995			(m->flags & PG_BUSY) ? 1 : 0, m->hold_count);
996		if ((m->queue - m->pc) == PQ_FREE)
997			panic("vm_page_free: freeing free page");
998		else
999			panic("vm_page_free: freeing busy page");
1000	}
1001#endif
1002
1003	vm_page_remove(m);
1004	vm_page_unqueue_nowakeup(m);
1005	if ((m->flags & PG_FICTITIOUS) != 0) {
1006		return 0;
1007	}
1008	if (m->wire_count != 0) {
1009		if (m->wire_count > 1) {
1010			panic("vm_page_free: invalid wire count (%d), pindex: 0x%x",
1011				m->wire_count, m->pindex);
1012		}
1013		m->wire_count = 0;
1014		cnt.v_wire_count--;
1015	}
1016
1017	if (oldobject && (oldobject->type == OBJT_VNODE) &&
1018		((oldobject->flags & OBJ_DEAD) == 0)) {
1019		struct vnode *vp;
1020		vp = (struct vnode *) oldobject->handle;
1021		if (vp && VSHOULDFREE(vp)) {
1022			if ((vp->v_flag & (VTBFREE|VDOOMED|VFREE)) == 0) {
1023				TAILQ_INSERT_TAIL(&vnode_tobefree_list, vp, v_freelist);
1024				vp->v_flag |= VTBFREE;
1025			}
1026		}
1027	}
1028
1029	return 1;
1030}
1031
1032/*
1033 * helper routine for vm_page_free and vm_page_free_zero
1034 */
1035static __inline void
1036vm_page_free_wakeup()
1037{
1038
1039/*
1040 * if pageout daemon needs pages, then tell it that there are
1041 * some free.
1042 */
1043	if (vm_pageout_pages_needed) {
1044		wakeup(&vm_pageout_pages_needed);
1045		vm_pageout_pages_needed = 0;
1046	}
1047	/*
1048	 * wakeup processes that are waiting on memory if we hit a
1049	 * high water mark. And wakeup scheduler process if we have
1050	 * lots of memory. this process will swapin processes.
1051	 */
1052	if (vm_pages_needed &&
1053		((cnt.v_free_count + cnt.v_cache_count) >= cnt.v_free_min)) {
1054		wakeup(&cnt.v_free_count);
1055		vm_pages_needed = 0;
1056	}
1057}
1058
1059/*
1060 *	vm_page_free:
1061 *
1062 *	Returns the given page to the free list,
1063 *	disassociating it with any VM object.
1064 *
1065 *	Object and page must be locked prior to entry.
1066 */
1067void
1068vm_page_free(m)
1069	register vm_page_t m;
1070{
1071	int s;
1072	struct vpgqueues *pq;
1073
1074	s = splvm();
1075
1076	cnt.v_tfree++;
1077
1078	if (!vm_page_freechk_and_unqueue(m)) {
1079		splx(s);
1080		return;
1081	}
1082
1083	m->queue = PQ_FREE + m->pc;
1084	pq = &vm_page_queues[m->queue];
1085	++(*pq->lcnt);
1086	++(*pq->cnt);
1087	/*
1088	 * If the pageout process is grabbing the page, it is likely
1089	 * that the page is NOT in the cache.  It is more likely that
1090	 * the page will be partially in the cache if it is being
1091	 * explicitly freed.
1092	 */
1093	if (curproc == pageproc) {
1094		TAILQ_INSERT_TAIL(pq->pl, m, pageq);
1095	} else {
1096		TAILQ_INSERT_HEAD(pq->pl, m, pageq);
1097	}
1098
1099	vm_page_free_wakeup();
1100	splx(s);
1101}
1102
1103void
1104vm_page_free_zero(m)
1105	register vm_page_t m;
1106{
1107	int s;
1108	struct vpgqueues *pq;
1109
1110	s = splvm();
1111
1112	cnt.v_tfree++;
1113
1114	if (!vm_page_freechk_and_unqueue(m)) {
1115		splx(s);
1116		return;
1117	}
1118
1119	m->queue = PQ_ZERO + m->pc;
1120	pq = &vm_page_queues[m->queue];
1121	++(*pq->lcnt);
1122	++(*pq->cnt);
1123
1124	TAILQ_INSERT_HEAD(pq->pl, m, pageq);
1125	++vm_page_zero_count;
1126	vm_page_free_wakeup();
1127	splx(s);
1128}
1129
1130/*
1131 *	vm_page_wire:
1132 *
1133 *	Mark this page as wired down by yet
1134 *	another map, removing it from paging queues
1135 *	as necessary.
1136 *
1137 *	The page queues must be locked.
1138 */
1139void
1140vm_page_wire(m)
1141	register vm_page_t m;
1142{
1143	int s;
1144
1145	if (m->wire_count == 0) {
1146		s = splvm();
1147		vm_page_unqueue(m);
1148		splx(s);
1149		cnt.v_wire_count++;
1150	}
1151	++(*vm_page_queues[PQ_NONE].lcnt);
1152	m->wire_count++;
1153	m->flags |= PG_MAPPED;
1154}
1155
1156/*
1157 *	vm_page_unwire:
1158 *
1159 *	Release one wiring of this page, potentially
1160 *	enabling it to be paged again.
1161 *
1162 *	The page queues must be locked.
1163 */
1164void
1165vm_page_unwire(m)
1166	register vm_page_t m;
1167{
1168	int s;
1169
1170	s = splvm();
1171
1172	if (m->wire_count > 0)
1173		m->wire_count--;
1174
1175	if (m->wire_count == 0) {
1176		cnt.v_wire_count--;
1177		TAILQ_INSERT_TAIL(&vm_page_queue_active, m, pageq);
1178		m->queue = PQ_ACTIVE;
1179		++(*vm_page_queues[PQ_ACTIVE].lcnt);
1180		cnt.v_active_count++;
1181	}
1182	splx(s);
1183}
1184
1185
1186/*
1187 *	vm_page_deactivate:
1188 *
1189 *	Returns the given page to the inactive list,
1190 *	indicating that no physical maps have access
1191 *	to this page.  [Used by the physical mapping system.]
1192 *
1193 *	The page queues must be locked.
1194 */
1195void
1196vm_page_deactivate(m)
1197	register vm_page_t m;
1198{
1199	int s;
1200
1201	/*
1202	 * Only move active pages -- ignore locked or already inactive ones.
1203	 *
1204	 * XXX: sometimes we get pages which aren't wired down or on any queue -
1205	 * we need to put them on the inactive queue also, otherwise we lose
1206	 * track of them. Paul Mackerras (paulus@cs.anu.edu.au) 9-Jan-93.
1207	 */
1208	if (m->queue == PQ_INACTIVE)
1209		return;
1210
1211	s = splvm();
1212	if (m->wire_count == 0 && m->hold_count == 0) {
1213		if ((m->queue - m->pc) == PQ_CACHE)
1214			cnt.v_reactivated++;
1215		vm_page_unqueue(m);
1216		TAILQ_INSERT_TAIL(&vm_page_queue_inactive, m, pageq);
1217		m->queue = PQ_INACTIVE;
1218		++(*vm_page_queues[PQ_INACTIVE].lcnt);
1219		cnt.v_inactive_count++;
1220	}
1221	splx(s);
1222}
1223
1224/*
1225 * vm_page_cache
1226 *
1227 * Put the specified page onto the page cache queue (if appropriate).
1228 */
1229void
1230vm_page_cache(m)
1231	register vm_page_t m;
1232{
1233	int s;
1234
1235	if ((m->flags & PG_BUSY) || m->busy || m->wire_count) {
1236		printf("vm_page_cache: attempting to cache busy page\n");
1237		return;
1238	}
1239	if ((m->queue - m->pc) == PQ_CACHE)
1240		return;
1241
1242	vm_page_protect(m, VM_PROT_NONE);
1243	if (m->dirty != 0) {
1244		panic("vm_page_cache: caching a dirty page, pindex: %d", m->pindex);
1245	}
1246	s = splvm();
1247	vm_page_unqueue_nowakeup(m);
1248	m->queue = PQ_CACHE + m->pc;
1249	++(*vm_page_queues[m->queue].lcnt);
1250	TAILQ_INSERT_TAIL(vm_page_queues[m->queue].pl, m, pageq);
1251	cnt.v_cache_count++;
1252	vm_page_free_wakeup();
1253	splx(s);
1254}
1255
1256
1257/*
1258 * mapping function for valid bits or for dirty bits in
1259 * a page
1260 */
1261inline int
1262vm_page_bits(int base, int size)
1263{
1264	u_short chunk;
1265
1266	if ((base == 0) && (size >= PAGE_SIZE))
1267		return VM_PAGE_BITS_ALL;
1268	size = (size + DEV_BSIZE - 1) & ~(DEV_BSIZE - 1);
1269	base = (base % PAGE_SIZE) / DEV_BSIZE;
1270	chunk = vm_page_dev_bsize_chunks[size / DEV_BSIZE];
1271	return (chunk << base) & VM_PAGE_BITS_ALL;
1272}
1273
1274/*
1275 * set a page valid and clean
1276 */
1277void
1278vm_page_set_validclean(m, base, size)
1279	vm_page_t m;
1280	int base;
1281	int size;
1282{
1283	int pagebits = vm_page_bits(base, size);
1284	m->valid |= pagebits;
1285	m->dirty &= ~pagebits;
1286	if( base == 0 && size == PAGE_SIZE)
1287		pmap_clear_modify(VM_PAGE_TO_PHYS(m));
1288}
1289
1290/*
1291 * set a page (partially) invalid
1292 */
1293void
1294vm_page_set_invalid(m, base, size)
1295	vm_page_t m;
1296	int base;
1297	int size;
1298{
1299	int bits;
1300
1301	m->valid &= ~(bits = vm_page_bits(base, size));
1302	if (m->valid == 0)
1303		m->dirty &= ~bits;
1304}
1305
1306/*
1307 * is (partial) page valid?
1308 */
1309int
1310vm_page_is_valid(m, base, size)
1311	vm_page_t m;
1312	int base;
1313	int size;
1314{
1315	int bits = vm_page_bits(base, size);
1316
1317	if (m->valid && ((m->valid & bits) == bits))
1318		return 1;
1319	else
1320		return 0;
1321}
1322
1323void
1324vm_page_test_dirty(m)
1325	vm_page_t m;
1326{
1327	if ((m->dirty != VM_PAGE_BITS_ALL) &&
1328	    pmap_is_modified(VM_PAGE_TO_PHYS(m))) {
1329		m->dirty = VM_PAGE_BITS_ALL;
1330	}
1331}
1332
1333/*
1334 * This interface is for merging with malloc() someday.
1335 * Even if we never implement compaction so that contiguous allocation
1336 * works after initialization time, malloc()'s data structures are good
1337 * for statistics and for allocations of less than a page.
1338 */
1339void *
1340contigmalloc1(size, type, flags, low, high, alignment, boundary, map)
1341	unsigned long size;	/* should be size_t here and for malloc() */
1342	struct malloc_type *type;
1343	int flags;
1344	unsigned long low;
1345	unsigned long high;
1346	unsigned long alignment;
1347	unsigned long boundary;
1348	vm_map_t map;
1349{
1350	int i, s, start;
1351	vm_offset_t addr, phys, tmp_addr;
1352	int pass;
1353	vm_page_t pga = vm_page_array;
1354
1355	size = round_page(size);
1356	if (size == 0)
1357		panic("contigmalloc1: size must not be 0");
1358	if ((alignment & (alignment - 1)) != 0)
1359		panic("contigmalloc1: alignment must be a power of 2");
1360	if ((boundary & (boundary - 1)) != 0)
1361		panic("contigmalloc1: boundary must be a power of 2");
1362
1363	start = 0;
1364	for (pass = 0; pass <= 1; pass++) {
1365		s = splvm();
1366again:
1367		/*
1368		 * Find first page in array that is free, within range, aligned, and
1369		 * such that the boundary won't be crossed.
1370		 */
1371		for (i = start; i < cnt.v_page_count; i++) {
1372			int pqtype;
1373			phys = VM_PAGE_TO_PHYS(&pga[i]);
1374			pqtype = pga[i].queue - pga[i].pc;
1375			if (((pqtype == PQ_ZERO) || (pqtype == PQ_FREE) || (pqtype == PQ_CACHE)) &&
1376			    (phys >= low) && (phys < high) &&
1377			    ((phys & (alignment - 1)) == 0) &&
1378			    (((phys ^ (phys + size - 1)) & ~(boundary - 1)) == 0))
1379				break;
1380		}
1381
1382		/*
1383		 * If the above failed or we will exceed the upper bound, fail.
1384		 */
1385		if ((i == cnt.v_page_count) ||
1386			((VM_PAGE_TO_PHYS(&pga[i]) + size) > high)) {
1387			vm_page_t m, next;
1388
1389again1:
1390			for (m = TAILQ_FIRST(&vm_page_queue_inactive);
1391				m != NULL;
1392				m = next) {
1393
1394				if (m->queue != PQ_INACTIVE) {
1395					break;
1396				}
1397
1398				next = TAILQ_NEXT(m, pageq);
1399				if (m->flags & PG_BUSY) {
1400					m->flags |= PG_WANTED;
1401					tsleep(m, PVM, "vpctw0", 0);
1402					goto again1;
1403				}
1404				vm_page_test_dirty(m);
1405				if (m->dirty) {
1406					if (m->object->type == OBJT_VNODE) {
1407						vn_lock(m->object->handle, LK_EXCLUSIVE | LK_RETRY, curproc);
1408						vm_object_page_clean(m->object, 0, 0, TRUE);
1409						VOP_UNLOCK(m->object->handle, 0, curproc);
1410						goto again1;
1411					} else if (m->object->type == OBJT_SWAP ||
1412								m->object->type == OBJT_DEFAULT) {
1413						vm_page_protect(m, VM_PROT_NONE);
1414						vm_pageout_flush(&m, 1, 0);
1415						goto again1;
1416					}
1417				}
1418				if ((m->dirty == 0) &&
1419					(m->busy == 0) &&
1420					(m->hold_count == 0))
1421					vm_page_cache(m);
1422			}
1423
1424			for (m = TAILQ_FIRST(&vm_page_queue_active);
1425				m != NULL;
1426				m = next) {
1427
1428				if (m->queue != PQ_ACTIVE) {
1429					break;
1430				}
1431
1432				next = TAILQ_NEXT(m, pageq);
1433				if (m->flags & PG_BUSY) {
1434					m->flags |= PG_WANTED;
1435					tsleep(m, PVM, "vpctw1", 0);
1436					goto again1;
1437				}
1438				vm_page_test_dirty(m);
1439				if (m->dirty) {
1440					if (m->object->type == OBJT_VNODE) {
1441						vn_lock(m->object->handle, LK_EXCLUSIVE | LK_RETRY, curproc);
1442						vm_object_page_clean(m->object, 0, 0, TRUE);
1443						VOP_UNLOCK(m->object->handle, 0, curproc);
1444						goto again1;
1445					} else if (m->object->type == OBJT_SWAP ||
1446								m->object->type == OBJT_DEFAULT) {
1447						vm_page_protect(m, VM_PROT_NONE);
1448						vm_pageout_flush(&m, 1, 0);
1449						goto again1;
1450					}
1451				}
1452				if ((m->dirty == 0) &&
1453					(m->busy == 0) &&
1454					(m->hold_count == 0))
1455					vm_page_cache(m);
1456			}
1457
1458			splx(s);
1459			continue;
1460		}
1461		start = i;
1462
1463		/*
1464		 * Check successive pages for contiguous and free.
1465		 */
1466		for (i = start + 1; i < (start + size / PAGE_SIZE); i++) {
1467			int pqtype;
1468			pqtype = pga[i].queue - pga[i].pc;
1469			if ((VM_PAGE_TO_PHYS(&pga[i]) !=
1470			    (VM_PAGE_TO_PHYS(&pga[i - 1]) + PAGE_SIZE)) ||
1471			    ((pqtype != PQ_ZERO) && (pqtype != PQ_FREE) && (pqtype != PQ_CACHE))) {
1472				start++;
1473				goto again;
1474			}
1475		}
1476
1477		for (i = start; i < (start + size / PAGE_SIZE); i++) {
1478			int pqtype;
1479			vm_page_t m = &pga[i];
1480
1481			pqtype = m->queue - m->pc;
1482			if (pqtype == PQ_CACHE)
1483				vm_page_free(m);
1484
1485			TAILQ_REMOVE(vm_page_queues[m->queue].pl, m, pageq);
1486			--(*vm_page_queues[m->queue].lcnt);
1487			cnt.v_free_count--;
1488			m->valid = VM_PAGE_BITS_ALL;
1489			m->flags = 0;
1490			m->dirty = 0;
1491			m->wire_count = 0;
1492			m->busy = 0;
1493			m->queue = PQ_NONE;
1494			m->object = NULL;
1495			vm_page_wire(m);
1496		}
1497
1498		/*
1499		 * We've found a contiguous chunk that meets are requirements.
1500		 * Allocate kernel VM, unfree and assign the physical pages to it and
1501		 * return kernel VM pointer.
1502		 */
1503		tmp_addr = addr = kmem_alloc_pageable(map, size);
1504		if (addr == 0) {
1505			/*
1506			 * XXX We almost never run out of kernel virtual
1507			 * space, so we don't make the allocated memory
1508			 * above available.
1509			 */
1510			splx(s);
1511			return (NULL);
1512		}
1513
1514		for (i = start; i < (start + size / PAGE_SIZE); i++) {
1515			vm_page_t m = &pga[i];
1516			vm_page_insert(m, kernel_object,
1517				OFF_TO_IDX(tmp_addr - VM_MIN_KERNEL_ADDRESS));
1518			pmap_kenter(tmp_addr, VM_PAGE_TO_PHYS(m));
1519			tmp_addr += PAGE_SIZE;
1520		}
1521
1522		splx(s);
1523		return ((void *)addr);
1524	}
1525	return NULL;
1526}
1527
1528void *
1529contigmalloc(size, type, flags, low, high, alignment, boundary)
1530	unsigned long size;	/* should be size_t here and for malloc() */
1531	struct malloc_type *type;
1532	int flags;
1533	unsigned long low;
1534	unsigned long high;
1535	unsigned long alignment;
1536	unsigned long boundary;
1537{
1538	return contigmalloc1(size, type, flags, low, high, alignment, boundary,
1539			     kernel_map);
1540}
1541
1542vm_offset_t
1543vm_page_alloc_contig(size, low, high, alignment)
1544	vm_offset_t size;
1545	vm_offset_t low;
1546	vm_offset_t high;
1547	vm_offset_t alignment;
1548{
1549	return ((vm_offset_t)contigmalloc1(size, M_DEVBUF, M_NOWAIT, low, high,
1550					  alignment, 0ul, kernel_map));
1551}
1552
1553#include "opt_ddb.h"
1554#ifdef DDB
1555#include <sys/kernel.h>
1556
1557#include <ddb/ddb.h>
1558
1559DB_SHOW_COMMAND(page, vm_page_print_page_info)
1560{
1561	db_printf("cnt.v_free_count: %d\n", cnt.v_free_count);
1562	db_printf("cnt.v_cache_count: %d\n", cnt.v_cache_count);
1563	db_printf("cnt.v_inactive_count: %d\n", cnt.v_inactive_count);
1564	db_printf("cnt.v_active_count: %d\n", cnt.v_active_count);
1565	db_printf("cnt.v_wire_count: %d\n", cnt.v_wire_count);
1566	db_printf("cnt.v_free_reserved: %d\n", cnt.v_free_reserved);
1567	db_printf("cnt.v_free_min: %d\n", cnt.v_free_min);
1568	db_printf("cnt.v_free_target: %d\n", cnt.v_free_target);
1569	db_printf("cnt.v_cache_min: %d\n", cnt.v_cache_min);
1570	db_printf("cnt.v_inactive_target: %d\n", cnt.v_inactive_target);
1571}
1572
1573DB_SHOW_COMMAND(pageq, vm_page_print_pageq_info)
1574{
1575	int i;
1576	db_printf("PQ_FREE:");
1577	for(i=0;i<PQ_L2_SIZE;i++) {
1578		db_printf(" %d", *vm_page_queues[PQ_FREE + i].lcnt);
1579	}
1580	db_printf("\n");
1581
1582	db_printf("PQ_CACHE:");
1583	for(i=0;i<PQ_L2_SIZE;i++) {
1584		db_printf(" %d", *vm_page_queues[PQ_CACHE + i].lcnt);
1585	}
1586	db_printf("\n");
1587
1588	db_printf("PQ_ZERO:");
1589	for(i=0;i<PQ_L2_SIZE;i++) {
1590		db_printf(" %d", *vm_page_queues[PQ_ZERO + i].lcnt);
1591	}
1592	db_printf("\n");
1593
1594	db_printf("PQ_ACTIVE: %d, PQ_INACTIVE: %d\n",
1595		*vm_page_queues[PQ_ACTIVE].lcnt,
1596		*vm_page_queues[PQ_INACTIVE].lcnt);
1597}
1598#endif /* DDB */
1599