uvm_page.c revision 1.52
1/*	$OpenBSD: uvm_page.c,v 1.52 2006/04/27 15:21:19 mickey Exp $	*/
2/*	$NetBSD: uvm_page.c,v 1.44 2000/11/27 08:40:04 chs Exp $	*/
3
4/*
5 * Copyright (c) 1997 Charles D. Cranor and Washington University.
6 * Copyright (c) 1991, 1993, The Regents of the University of California.
7 *
8 * All rights reserved.
9 *
10 * This code is derived from software contributed to Berkeley by
11 * The Mach Operating System project at Carnegie-Mellon University.
12 *
13 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions
15 * are met:
16 * 1. Redistributions of source code must retain the above copyright
17 *    notice, this list of conditions and the following disclaimer.
18 * 2. Redistributions in binary form must reproduce the above copyright
19 *    notice, this list of conditions and the following disclaimer in the
20 *    documentation and/or other materials provided with the distribution.
21 * 3. All advertising materials mentioning features or use of this software
22 *    must display the following acknowledgement:
23 *	This product includes software developed by Charles D. Cranor,
24 *      Washington University, the University of California, Berkeley and
25 *      its contributors.
26 * 4. Neither the name of the University nor the names of its contributors
27 *    may be used to endorse or promote products derived from this software
28 *    without specific prior written permission.
29 *
30 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
31 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
32 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
33 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
34 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
35 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
36 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
37 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
38 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
39 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
40 * SUCH DAMAGE.
41 *
42 *	@(#)vm_page.c   8.3 (Berkeley) 3/21/94
43 * from: Id: uvm_page.c,v 1.1.2.18 1998/02/06 05:24:42 chs Exp
44 *
45 *
46 * Copyright (c) 1987, 1990 Carnegie-Mellon University.
47 * All rights reserved.
48 *
49 * Permission to use, copy, modify and distribute this software and
50 * its documentation is hereby granted, provided that both the copyright
51 * notice and this permission notice appear in all copies of the
52 * software, derivative works or modified versions, and any portions
53 * thereof, and that both notices appear in supporting documentation.
54 *
55 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
56 * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
57 * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
58 *
59 * Carnegie Mellon requests users of this software to return to
60 *
61 *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
62 *  School of Computer Science
63 *  Carnegie Mellon University
64 *  Pittsburgh PA 15213-3890
65 *
66 * any improvements or extensions that they make and grant Carnegie the
67 * rights to redistribute these changes.
68 */
69
70/*
71 * uvm_page.c: page ops.
72 */
73
74#define UVM_PAGE                /* pull in uvm_page.h functions */
75#include <sys/param.h>
76#include <sys/systm.h>
77#include <sys/malloc.h>
78#include <sys/sched.h>
79#include <sys/kernel.h>
80#include <sys/vnode.h>
81
82#include <uvm/uvm.h>
83
84/*
85 * global vars... XXXCDC: move to uvm. structure.
86 */
87
88/*
89 * physical memory config is stored in vm_physmem.
90 */
91
92struct vm_physseg vm_physmem[VM_PHYSSEG_MAX];	/* XXXCDC: uvm.physmem */
93int vm_nphysseg = 0;				/* XXXCDC: uvm.nphysseg */
94
95/*
96 * Some supported CPUs in a given architecture don't support all
97 * of the things necessary to do idle page zero'ing efficiently.
98 * We therefore provide a way to disable it from machdep code here.
99 */
100
101/*
102 * XXX disabled until we can find a way to do this without causing
103 * problems for either cpu caches or DMA latency.
104 */
105boolean_t vm_page_zero_enable = FALSE;
106
107/*
108 * local variables
109 */
110
111/*
112 * these variables record the values returned by vm_page_bootstrap,
113 * for debugging purposes.  The implementation of uvm_pageboot_alloc
114 * and pmap_startup here also uses them internally.
115 */
116
117static vaddr_t      virtual_space_start;
118static vaddr_t      virtual_space_end;
119
120/*
121 * we use a hash table with only one bucket during bootup.  we will
122 * later rehash (resize) the hash table once the allocator is ready.
123 * we static allocate the one bootstrap bucket below...
124 */
125
126static struct pglist uvm_bootbucket;
127
128/*
129 * History
130 */
131UVMHIST_DECL(pghist);
132
133/*
134 * local prototypes
135 */
136
137static void uvm_pageinsert(struct vm_page *);
138static void uvm_pageremove(struct vm_page *);
139
140/*
141 * inline functions
142 */
143
144/*
145 * uvm_pageinsert: insert a page in the object and the hash table
146 *
147 * => caller must lock object
148 * => caller must lock page queues
149 * => call should have already set pg's object and offset pointers
150 *    and bumped the version counter
151 */
152
153__inline static void
154uvm_pageinsert(pg)
155	struct vm_page *pg;
156{
157	struct pglist *buck;
158	int s;
159	UVMHIST_FUNC("uvm_pageinsert"); UVMHIST_CALLED(pghist);
160
161	KASSERT((pg->flags & PG_TABLED) == 0);
162	buck = &uvm.page_hash[uvm_pagehash(pg->uobject,pg->offset)];
163	s = splvm();
164	simple_lock(&uvm.hashlock);
165	TAILQ_INSERT_TAIL(buck, pg, hashq);	/* put in hash */
166	simple_unlock(&uvm.hashlock);
167	splx(s);
168
169	TAILQ_INSERT_TAIL(&pg->uobject->memq, pg, listq); /* put in object */
170	pg->flags |= PG_TABLED;
171	pg->uobject->uo_npages++;
172}
173
174/*
175 * uvm_page_remove: remove page from object and hash
176 *
177 * => caller must lock object
178 * => caller must lock page queues
179 */
180
181static __inline void
182uvm_pageremove(pg)
183	struct vm_page *pg;
184{
185	struct pglist *buck;
186	int s;
187	UVMHIST_FUNC("uvm_pageremove"); UVMHIST_CALLED(pghist);
188
189	KASSERT(pg->flags & PG_TABLED);
190	buck = &uvm.page_hash[uvm_pagehash(pg->uobject,pg->offset)];
191	s = splvm();
192	simple_lock(&uvm.hashlock);
193	TAILQ_REMOVE(buck, pg, hashq);
194	simple_unlock(&uvm.hashlock);
195	splx(s);
196
197#ifdef UBC
198	if (pg->uobject->pgops == &uvm_vnodeops) {
199		uvm_pgcnt_vnode--;
200	}
201#endif
202
203	/* object should be locked */
204	TAILQ_REMOVE(&pg->uobject->memq, pg, listq);
205
206	pg->flags &= ~PG_TABLED;
207	pg->uobject->uo_npages--;
208	pg->uobject = NULL;
209	pg->version++;
210}
211
212/*
213 * uvm_page_init: init the page system.   called from uvm_init().
214 *
215 * => we return the range of kernel virtual memory in kvm_startp/kvm_endp
216 */
217
218void
219uvm_page_init(kvm_startp, kvm_endp)
220	vaddr_t *kvm_startp, *kvm_endp;
221{
222	vsize_t freepages, pagecount, n;
223	vm_page_t pagearray;
224	int lcv, i;
225	paddr_t paddr;
226#if defined(UVMHIST)
227	static struct uvm_history_ent pghistbuf[100];
228#endif
229
230	UVMHIST_FUNC("uvm_page_init");
231	UVMHIST_INIT_STATIC(pghist, pghistbuf);
232	UVMHIST_CALLED(pghist);
233
234	/*
235	 * init the page queues and page queue locks
236	 */
237
238	for (lcv = 0; lcv < VM_NFREELIST; lcv++) {
239		for (i = 0; i < PGFL_NQUEUES; i++)
240			TAILQ_INIT(&uvm.page_free[lcv].pgfl_queues[i]);
241	}
242	TAILQ_INIT(&uvm.page_active);
243	TAILQ_INIT(&uvm.page_inactive_swp);
244	TAILQ_INIT(&uvm.page_inactive_obj);
245	simple_lock_init(&uvm.pageqlock);
246	simple_lock_init(&uvm.fpageqlock);
247
248	/*
249	 * init the <obj,offset> => <page> hash table.  for now
250	 * we just have one bucket (the bootstrap bucket).  later on we
251	 * will allocate new buckets as we dynamically resize the hash table.
252	 */
253
254	uvm.page_nhash = 1;			/* 1 bucket */
255	uvm.page_hashmask = 0;			/* mask for hash function */
256	uvm.page_hash = &uvm_bootbucket;	/* install bootstrap bucket */
257	TAILQ_INIT(uvm.page_hash);		/* init hash table */
258	simple_lock_init(&uvm.hashlock);	/* init hash table lock */
259
260	/*
261	 * allocate vm_page structures.
262	 */
263
264	/*
265	 * sanity check:
266	 * before calling this function the MD code is expected to register
267	 * some free RAM with the uvm_page_physload() function.   our job
268	 * now is to allocate vm_page structures for this memory.
269	 */
270
271	if (vm_nphysseg == 0)
272		panic("uvm_page_bootstrap: no memory pre-allocated");
273
274	/*
275	 * first calculate the number of free pages...
276	 *
277	 * note that we use start/end rather than avail_start/avail_end.
278	 * this allows us to allocate extra vm_page structures in case we
279	 * want to return some memory to the pool after booting.
280	 */
281
282	freepages = 0;
283	for (lcv = 0 ; lcv < vm_nphysseg ; lcv++)
284		freepages += (vm_physmem[lcv].end - vm_physmem[lcv].start);
285
286	/*
287	 * we now know we have (PAGE_SIZE * freepages) bytes of memory we can
288	 * use.   for each page of memory we use we need a vm_page structure.
289	 * thus, the total number of pages we can use is the total size of
290	 * the memory divided by the PAGE_SIZE plus the size of the vm_page
291	 * structure.   we add one to freepages as a fudge factor to avoid
292	 * truncation errors (since we can only allocate in terms of whole
293	 * pages).
294	 */
295
296	pagecount = (((paddr_t)freepages + 1) << PAGE_SHIFT) /
297	    (PAGE_SIZE + sizeof(struct vm_page));
298	pagearray = (vm_page_t)uvm_pageboot_alloc(pagecount *
299	    sizeof(struct vm_page));
300	memset(pagearray, 0, pagecount * sizeof(struct vm_page));
301
302	/*
303	 * init the vm_page structures and put them in the correct place.
304	 */
305
306	for (lcv = 0 ; lcv < vm_nphysseg ; lcv++) {
307		n = vm_physmem[lcv].end - vm_physmem[lcv].start;
308		if (n > pagecount) {
309			printf("uvm_page_init: lost %ld page(s) in init\n",
310			    (long)(n - pagecount));
311			panic("uvm_page_init");  /* XXXCDC: shouldn't happen? */
312			/* n = pagecount; */
313		}
314
315		/* set up page array pointers */
316		vm_physmem[lcv].pgs = pagearray;
317		pagearray += n;
318		pagecount -= n;
319		vm_physmem[lcv].lastpg = vm_physmem[lcv].pgs + (n - 1);
320
321		/* init and free vm_pages (we've already zeroed them) */
322		paddr = ptoa(vm_physmem[lcv].start);
323		for (i = 0 ; i < n ; i++, paddr += PAGE_SIZE) {
324			vm_physmem[lcv].pgs[i].phys_addr = paddr;
325#ifdef __HAVE_VM_PAGE_MD
326			VM_MDPAGE_INIT(&vm_physmem[lcv].pgs[i]);
327#endif
328			if (atop(paddr) >= vm_physmem[lcv].avail_start &&
329			    atop(paddr) <= vm_physmem[lcv].avail_end) {
330				uvmexp.npages++;
331				/* add page to free pool */
332				uvm_pagefree(&vm_physmem[lcv].pgs[i]);
333			}
334		}
335	}
336
337	/*
338	 * pass up the values of virtual_space_start and
339	 * virtual_space_end (obtained by uvm_pageboot_alloc) to the upper
340	 * layers of the VM.
341	 */
342
343	*kvm_startp = round_page(virtual_space_start);
344	*kvm_endp = trunc_page(virtual_space_end);
345
346	/*
347	 * init locks for kernel threads
348	 */
349
350	simple_lock_init(&uvm.pagedaemon_lock);
351	simple_lock_init(&uvm.aiodoned_lock);
352
353	/*
354	 * init reserve thresholds
355	 * XXXCDC - values may need adjusting
356	 */
357	uvmexp.reserve_pagedaemon = 4;
358	uvmexp.reserve_kernel = 6;
359	uvmexp.anonminpct = 10;
360	uvmexp.vnodeminpct = 10;
361	uvmexp.vtextminpct = 5;
362	uvmexp.anonmin = uvmexp.anonminpct * 256 / 100;
363	uvmexp.vnodemin = uvmexp.vnodeminpct * 256 / 100;
364	uvmexp.vtextmin = uvmexp.vtextminpct * 256 / 100;
365
366  	/*
367	 * determine if we should zero pages in the idle loop.
368	 */
369
370	uvm.page_idle_zero = vm_page_zero_enable;
371
372	/*
373	 * done!
374	 */
375
376	uvm.page_init_done = TRUE;
377}
378
379/*
380 * uvm_setpagesize: set the page size
381 *
382 * => sets page_shift and page_mask from uvmexp.pagesize.
383 */
384
385void
386uvm_setpagesize()
387{
388	if (uvmexp.pagesize == 0)
389		uvmexp.pagesize = DEFAULT_PAGE_SIZE;
390	uvmexp.pagemask = uvmexp.pagesize - 1;
391	if ((uvmexp.pagemask & uvmexp.pagesize) != 0)
392		panic("uvm_setpagesize: page size not a power of two");
393	for (uvmexp.pageshift = 0; ; uvmexp.pageshift++)
394		if ((1 << uvmexp.pageshift) == uvmexp.pagesize)
395			break;
396}
397
398/*
399 * uvm_pageboot_alloc: steal memory from physmem for bootstrapping
400 */
401
402vaddr_t
403uvm_pageboot_alloc(size)
404	vsize_t size;
405{
406#if defined(PMAP_STEAL_MEMORY)
407	vaddr_t addr;
408
409	/*
410	 * defer bootstrap allocation to MD code (it may want to allocate
411	 * from a direct-mapped segment).  pmap_steal_memory should round
412	 * off virtual_space_start/virtual_space_end.
413	 */
414
415	addr = pmap_steal_memory(size, &virtual_space_start,
416	    &virtual_space_end);
417
418	return(addr);
419
420#else /* !PMAP_STEAL_MEMORY */
421
422	static boolean_t initialized = FALSE;
423	vaddr_t addr, vaddr;
424	paddr_t paddr;
425
426	/* round to page size */
427	size = round_page(size);
428
429	/*
430	 * on first call to this function, initialize ourselves.
431	 */
432	if (initialized == FALSE) {
433		pmap_virtual_space(&virtual_space_start, &virtual_space_end);
434
435		/* round it the way we like it */
436		virtual_space_start = round_page(virtual_space_start);
437		virtual_space_end = trunc_page(virtual_space_end);
438
439		initialized = TRUE;
440	}
441
442	/*
443	 * allocate virtual memory for this request
444	 */
445	if (virtual_space_start == virtual_space_end ||
446	    (virtual_space_end - virtual_space_start) < size)
447		panic("uvm_pageboot_alloc: out of virtual space");
448
449	addr = virtual_space_start;
450
451#ifdef PMAP_GROWKERNEL
452	/*
453	 * If the kernel pmap can't map the requested space,
454	 * then allocate more resources for it.
455	 */
456	if (uvm_maxkaddr < (addr + size)) {
457		uvm_maxkaddr = pmap_growkernel(addr + size);
458		if (uvm_maxkaddr < (addr + size))
459			panic("uvm_pageboot_alloc: pmap_growkernel() failed");
460	}
461#endif
462
463	virtual_space_start += size;
464
465	/*
466	 * allocate and mapin physical pages to back new virtual pages
467	 */
468
469	for (vaddr = round_page(addr) ; vaddr < addr + size ;
470	    vaddr += PAGE_SIZE) {
471
472		if (!uvm_page_physget(&paddr))
473			panic("uvm_pageboot_alloc: out of memory");
474
475		/*
476		 * Note this memory is no longer managed, so using
477		 * pmap_kenter is safe.
478		 */
479		pmap_kenter_pa(vaddr, paddr, VM_PROT_READ|VM_PROT_WRITE);
480	}
481	pmap_update(pmap_kernel());
482	return(addr);
483#endif	/* PMAP_STEAL_MEMORY */
484}
485
486#if !defined(PMAP_STEAL_MEMORY)
487/*
488 * uvm_page_physget: "steal" one page from the vm_physmem structure.
489 *
490 * => attempt to allocate it off the end of a segment in which the "avail"
491 *    values match the start/end values.   if we can't do that, then we
492 *    will advance both values (making them equal, and removing some
493 *    vm_page structures from the non-avail area).
494 * => return false if out of memory.
495 */
496
497/* subroutine: try to allocate from memory chunks on the specified freelist */
498static boolean_t uvm_page_physget_freelist(paddr_t *, int);
499
500static boolean_t
501uvm_page_physget_freelist(paddrp, freelist)
502	paddr_t *paddrp;
503	int freelist;
504{
505	int lcv, x;
506	UVMHIST_FUNC("uvm_page_physget_freelist"); UVMHIST_CALLED(pghist);
507
508	/* pass 1: try allocating from a matching end */
509#if (VM_PHYSSEG_STRAT == VM_PSTRAT_BIGFIRST) || \
510	(VM_PHYSSEG_STRAT == VM_PSTRAT_BSEARCH)
511	for (lcv = vm_nphysseg - 1 ; lcv >= 0 ; lcv--)
512#else
513	for (lcv = 0 ; lcv < vm_nphysseg ; lcv++)
514#endif
515	{
516
517		if (uvm.page_init_done == TRUE)
518			panic("uvm_page_physget: called _after_ bootstrap");
519
520		if (vm_physmem[lcv].free_list != freelist)
521			continue;
522
523		/* try from front */
524		if (vm_physmem[lcv].avail_start == vm_physmem[lcv].start &&
525		    vm_physmem[lcv].avail_start < vm_physmem[lcv].avail_end) {
526			*paddrp = ptoa(vm_physmem[lcv].avail_start);
527			vm_physmem[lcv].avail_start++;
528			vm_physmem[lcv].start++;
529			/* nothing left?   nuke it */
530			if (vm_physmem[lcv].avail_start ==
531			    vm_physmem[lcv].end) {
532				if (vm_nphysseg == 1)
533				    panic("uvm_page_physget: out of memory!");
534				vm_nphysseg--;
535				for (x = lcv ; x < vm_nphysseg ; x++)
536					/* structure copy */
537					vm_physmem[x] = vm_physmem[x+1];
538			}
539			return (TRUE);
540		}
541
542		/* try from rear */
543		if (vm_physmem[lcv].avail_end == vm_physmem[lcv].end &&
544		    vm_physmem[lcv].avail_start < vm_physmem[lcv].avail_end) {
545			*paddrp = ptoa(vm_physmem[lcv].avail_end - 1);
546			vm_physmem[lcv].avail_end--;
547			vm_physmem[lcv].end--;
548			/* nothing left?   nuke it */
549			if (vm_physmem[lcv].avail_end ==
550			    vm_physmem[lcv].start) {
551				if (vm_nphysseg == 1)
552				    panic("uvm_page_physget: out of memory!");
553				vm_nphysseg--;
554				for (x = lcv ; x < vm_nphysseg ; x++)
555					/* structure copy */
556					vm_physmem[x] = vm_physmem[x+1];
557			}
558			return (TRUE);
559		}
560	}
561
562	/* pass2: forget about matching ends, just allocate something */
563#if (VM_PHYSSEG_STRAT == VM_PSTRAT_BIGFIRST) || \
564	(VM_PHYSSEG_STRAT == VM_PSTRAT_BSEARCH)
565	for (lcv = vm_nphysseg - 1 ; lcv >= 0 ; lcv--)
566#else
567	for (lcv = 0 ; lcv < vm_nphysseg ; lcv++)
568#endif
569	{
570
571		/* any room in this bank? */
572		if (vm_physmem[lcv].avail_start >= vm_physmem[lcv].avail_end)
573			continue;  /* nope */
574
575		*paddrp = ptoa(vm_physmem[lcv].avail_start);
576		vm_physmem[lcv].avail_start++;
577		/* truncate! */
578		vm_physmem[lcv].start = vm_physmem[lcv].avail_start;
579
580		/* nothing left?   nuke it */
581		if (vm_physmem[lcv].avail_start == vm_physmem[lcv].end) {
582			if (vm_nphysseg == 1)
583				panic("uvm_page_physget: out of memory!");
584			vm_nphysseg--;
585			for (x = lcv ; x < vm_nphysseg ; x++)
586				/* structure copy */
587				vm_physmem[x] = vm_physmem[x+1];
588		}
589		return (TRUE);
590	}
591
592	return (FALSE);        /* whoops! */
593}
594
595boolean_t
596uvm_page_physget(paddrp)
597	paddr_t *paddrp;
598{
599	int i;
600	UVMHIST_FUNC("uvm_page_physget"); UVMHIST_CALLED(pghist);
601
602	/* try in the order of freelist preference */
603	for (i = 0; i < VM_NFREELIST; i++)
604		if (uvm_page_physget_freelist(paddrp, i) == TRUE)
605			return (TRUE);
606	return (FALSE);
607}
608#endif /* PMAP_STEAL_MEMORY */
609
610/*
611 * uvm_page_physload: load physical memory into VM system
612 *
613 * => all args are PFs
614 * => all pages in start/end get vm_page structures
615 * => areas marked by avail_start/avail_end get added to the free page pool
616 * => we are limited to VM_PHYSSEG_MAX physical memory segments
617 */
618
619void
620uvm_page_physload(start, end, avail_start, avail_end, free_list)
621	paddr_t start, end, avail_start, avail_end;
622	int free_list;
623{
624	int preload, lcv;
625	psize_t npages;
626	struct vm_page *pgs;
627	struct vm_physseg *ps;
628
629	if (uvmexp.pagesize == 0)
630		panic("uvm_page_physload: page size not set!");
631
632	if (free_list >= VM_NFREELIST || free_list < VM_FREELIST_DEFAULT)
633		panic("uvm_page_physload: bad free list %d", free_list);
634
635	if (start >= end)
636		panic("uvm_page_physload: start >= end");
637
638	/*
639	 * do we have room?
640	 */
641	if (vm_nphysseg == VM_PHYSSEG_MAX) {
642		printf("uvm_page_physload: unable to load physical memory "
643		    "segment\n");
644		printf("\t%d segments allocated, ignoring 0x%llx -> 0x%llx\n",
645		    VM_PHYSSEG_MAX, (long long)start, (long long)end);
646		printf("\tincrease VM_PHYSSEG_MAX\n");
647		return;
648	}
649
650	/*
651	 * check to see if this is a "preload" (i.e. uvm_mem_init hasn't been
652	 * called yet, so malloc is not available).
653	 */
654	for (lcv = 0 ; lcv < vm_nphysseg ; lcv++) {
655		if (vm_physmem[lcv].pgs)
656			break;
657	}
658	preload = (lcv == vm_nphysseg);
659
660	/*
661	 * if VM is already running, attempt to malloc() vm_page structures
662	 */
663	if (!preload) {
664#if defined(VM_PHYSSEG_NOADD)
665		panic("uvm_page_physload: tried to add RAM after vm_mem_init");
666#else
667		/* XXXCDC: need some sort of lockout for this case */
668		paddr_t paddr;
669		npages = end - start;  /* # of pages */
670		pgs = (vm_page *)uvm_km_alloc(kernel_map,
671		    sizeof(struct vm_page) * npages);
672		if (pgs == NULL) {
673			printf("uvm_page_physload: can not malloc vm_page "
674			    "structs for segment\n");
675			printf("\tignoring 0x%lx -> 0x%lx\n", start, end);
676			return;
677		}
678		/* zero data, init phys_addr and free_list, and free pages */
679		memset(pgs, 0, sizeof(struct vm_page) * npages);
680		for (lcv = 0, paddr = ptoa(start) ;
681				 lcv < npages ; lcv++, paddr += PAGE_SIZE) {
682			pgs[lcv].phys_addr = paddr;
683			pgs[lcv].free_list = free_list;
684			if (atop(paddr) >= avail_start &&
685			    atop(paddr) <= avail_end)
686				uvm_pagefree(&pgs[lcv]);
687		}
688		/* XXXCDC: incomplete: need to update uvmexp.free, what else? */
689		/* XXXCDC: need hook to tell pmap to rebuild pv_list, etc... */
690#endif
691	} else {
692
693		/* gcc complains if these don't get init'd */
694		pgs = NULL;
695		npages = 0;
696
697	}
698
699	/*
700	 * now insert us in the proper place in vm_physmem[]
701	 */
702
703#if (VM_PHYSSEG_STRAT == VM_PSTRAT_RANDOM)
704
705	/* random: put it at the end (easy!) */
706	ps = &vm_physmem[vm_nphysseg];
707
708#elif (VM_PHYSSEG_STRAT == VM_PSTRAT_BSEARCH)
709
710	{
711		int x;
712		/* sort by address for binary search */
713		for (lcv = 0 ; lcv < vm_nphysseg ; lcv++)
714			if (start < vm_physmem[lcv].start)
715				break;
716		ps = &vm_physmem[lcv];
717		/* move back other entries, if necessary ... */
718		for (x = vm_nphysseg ; x > lcv ; x--)
719			/* structure copy */
720			vm_physmem[x] = vm_physmem[x - 1];
721	}
722
723#elif (VM_PHYSSEG_STRAT == VM_PSTRAT_BIGFIRST)
724
725	{
726		int x;
727		/* sort by largest segment first */
728		for (lcv = 0 ; lcv < vm_nphysseg ; lcv++)
729			if ((end - start) >
730			    (vm_physmem[lcv].end - vm_physmem[lcv].start))
731				break;
732		ps = &vm_physmem[lcv];
733		/* move back other entries, if necessary ... */
734		for (x = vm_nphysseg ; x > lcv ; x--)
735			/* structure copy */
736			vm_physmem[x] = vm_physmem[x - 1];
737	}
738
739#else
740
741	panic("uvm_page_physload: unknown physseg strategy selected!");
742
743#endif
744
745	ps->start = start;
746	ps->end = end;
747	ps->avail_start = avail_start;
748	ps->avail_end = avail_end;
749	if (preload) {
750		ps->pgs = NULL;
751	} else {
752		ps->pgs = pgs;
753		ps->lastpg = pgs + npages - 1;
754	}
755	ps->free_list = free_list;
756	vm_nphysseg++;
757
758	/*
759	 * done!
760	 */
761
762	if (!preload)
763		uvm_page_rehash();
764
765	return;
766}
767
768/*
769 * uvm_page_rehash: reallocate hash table based on number of free pages.
770 */
771
772void
773uvm_page_rehash()
774{
775	int freepages, lcv, bucketcount, s, oldcount;
776	struct pglist *newbuckets, *oldbuckets;
777	struct vm_page *pg;
778	size_t newsize, oldsize;
779
780	/*
781	 * compute number of pages that can go in the free pool
782	 */
783
784	freepages = 0;
785	for (lcv = 0 ; lcv < vm_nphysseg ; lcv++)
786		freepages +=
787		    (vm_physmem[lcv].avail_end - vm_physmem[lcv].avail_start);
788
789	/*
790	 * compute number of buckets needed for this number of pages
791	 */
792
793	bucketcount = 1;
794	while (bucketcount < freepages)
795		bucketcount = bucketcount * 2;
796
797	/*
798	 * compute the size of the current table and new table.
799	 */
800
801	oldbuckets = uvm.page_hash;
802	oldcount = uvm.page_nhash;
803	oldsize = round_page(sizeof(struct pglist) * oldcount);
804	newsize = round_page(sizeof(struct pglist) * bucketcount);
805
806	/*
807	 * allocate the new buckets
808	 */
809
810	newbuckets = (struct pglist *) uvm_km_alloc(kernel_map, newsize);
811	if (newbuckets == NULL) {
812		printf("uvm_page_physrehash: WARNING: could not grow page "
813		    "hash table\n");
814		return;
815	}
816	for (lcv = 0 ; lcv < bucketcount ; lcv++)
817		TAILQ_INIT(&newbuckets[lcv]);
818
819	/*
820	 * now replace the old buckets with the new ones and rehash everything
821	 */
822
823	s = splvm();
824	simple_lock(&uvm.hashlock);
825	uvm.page_hash = newbuckets;
826	uvm.page_nhash = bucketcount;
827	uvm.page_hashmask = bucketcount - 1;  /* power of 2 */
828
829	/* ... and rehash */
830	for (lcv = 0 ; lcv < oldcount ; lcv++) {
831		while ((pg = TAILQ_FIRST(&oldbuckets[lcv])) != NULL) {
832			TAILQ_REMOVE(&oldbuckets[lcv], pg, hashq);
833			TAILQ_INSERT_TAIL(
834			  &uvm.page_hash[uvm_pagehash(pg->uobject, pg->offset)],
835			  pg, hashq);
836		}
837	}
838	simple_unlock(&uvm.hashlock);
839	splx(s);
840
841	/*
842	 * free old bucket array if is not the boot-time table
843	 */
844
845	if (oldbuckets != &uvm_bootbucket)
846		uvm_km_free(kernel_map, (vaddr_t) oldbuckets, oldsize);
847
848	/*
849	 * done
850	 */
851	return;
852}
853
854
855#if 1 /* XXXCDC: TMP TMP TMP DEBUG DEBUG DEBUG */
856
857void uvm_page_physdump(void); /* SHUT UP GCC */
858
859/* call from DDB */
860void
861uvm_page_physdump()
862{
863	int lcv;
864
865	printf("rehash: physical memory config [segs=%d of %d]:\n",
866				 vm_nphysseg, VM_PHYSSEG_MAX);
867	for (lcv = 0 ; lcv < vm_nphysseg ; lcv++)
868		printf("0x%llx->0x%llx [0x%llx->0x%llx]\n",
869		    (long long)vm_physmem[lcv].start,
870		    (long long)vm_physmem[lcv].end,
871		    (long long)vm_physmem[lcv].avail_start,
872		    (long long)vm_physmem[lcv].avail_end);
873	printf("STRATEGY = ");
874	switch (VM_PHYSSEG_STRAT) {
875	case VM_PSTRAT_RANDOM: printf("RANDOM\n"); break;
876	case VM_PSTRAT_BSEARCH: printf("BSEARCH\n"); break;
877	case VM_PSTRAT_BIGFIRST: printf("BIGFIRST\n"); break;
878	default: printf("<<UNKNOWN>>!!!!\n");
879	}
880	printf("number of buckets = %d\n", uvm.page_nhash);
881}
882#endif
883
884/*
885 * uvm_pagealloc_strat: allocate vm_page from a particular free list.
886 *
887 * => return null if no pages free
888 * => wake up pagedaemon if number of free pages drops below low water mark
889 * => if obj != NULL, obj must be locked (to put in hash)
890 * => if anon != NULL, anon must be locked (to put in anon)
891 * => only one of obj or anon can be non-null
892 * => caller must activate/deactivate page if it is not wired.
893 * => free_list is ignored if strat == UVM_PGA_STRAT_NORMAL.
894 * => policy decision: it is more important to pull a page off of the
895 *	appropriate priority free list than it is to get a zero'd or
896 *	unknown contents page.  This is because we live with the
897 *	consequences of a bad free list decision for the entire
898 *	lifetime of the page, e.g. if the page comes from memory that
899 *	is slower to access.
900 */
901
902struct vm_page *
903uvm_pagealloc_strat(obj, off, anon, flags, strat, free_list)
904	struct uvm_object *obj;
905	voff_t off;
906	int flags;
907	struct vm_anon *anon;
908	int strat, free_list;
909{
910	int lcv, try1, try2, s, zeroit = 0;
911	struct vm_page *pg;
912	struct pglist *freeq;
913	struct pgfreelist *pgfl;
914	boolean_t use_reserve;
915	UVMHIST_FUNC("uvm_pagealloc_strat"); UVMHIST_CALLED(pghist);
916
917	KASSERT(obj == NULL || anon == NULL);
918	KASSERT(off == trunc_page(off));
919	s = uvm_lock_fpageq();
920
921	/*
922	 * check to see if we need to generate some free pages waking
923	 * the pagedaemon.
924	 */
925
926#ifdef UBC
927	if (uvmexp.free + uvmexp.paging < uvmexp.freemin ||
928	    (uvmexp.free + uvmexp.paging < uvmexp.freetarg &&
929	     uvmexp.inactive < uvmexp.inactarg)) {
930		wakeup(&uvm.pagedaemon);
931	}
932#else
933	if (uvmexp.free < uvmexp.freemin || (uvmexp.free < uvmexp.freetarg &&
934	    uvmexp.inactive < uvmexp.inactarg))
935		wakeup(&uvm.pagedaemon);
936#endif
937
938	/*
939	 * fail if any of these conditions is true:
940	 * [1]  there really are no free pages, or
941	 * [2]  only kernel "reserved" pages remain and
942	 *        the page isn't being allocated to a kernel object.
943	 * [3]  only pagedaemon "reserved" pages remain and
944	 *        the requestor isn't the pagedaemon.
945	 */
946
947	use_reserve = (flags & UVM_PGA_USERESERVE) ||
948		(obj && UVM_OBJ_IS_KERN_OBJECT(obj));
949	if ((uvmexp.free <= uvmexp.reserve_kernel && !use_reserve) ||
950	    (uvmexp.free <= uvmexp.reserve_pagedaemon &&
951	     !(use_reserve && (curproc == uvm.pagedaemon_proc ||
952				curproc == syncerproc))))
953		goto fail;
954
955#if PGFL_NQUEUES != 2
956#error uvm_pagealloc_strat needs to be updated
957#endif
958
959	/*
960	 * If we want a zero'd page, try the ZEROS queue first, otherwise
961	 * we try the UNKNOWN queue first.
962	 */
963	if (flags & UVM_PGA_ZERO) {
964		try1 = PGFL_ZEROS;
965		try2 = PGFL_UNKNOWN;
966	} else {
967		try1 = PGFL_UNKNOWN;
968		try2 = PGFL_ZEROS;
969	}
970
971	UVMHIST_LOG(pghist, "obj=%p off=%llx anon=%x flags=%x",
972	    obj, off, flags, anon);
973	UVMHIST_LOG(pghist, "strat=%d free_list=%d", strat, free_list, 0, 0);
974 again:
975	switch (strat) {
976	case UVM_PGA_STRAT_NORMAL:
977		/* Check all freelists in descending priority order. */
978		for (lcv = 0; lcv < VM_NFREELIST; lcv++) {
979			pgfl = &uvm.page_free[lcv];
980			if ((pg = TAILQ_FIRST((freeq =
981			      &pgfl->pgfl_queues[try1]))) != NULL ||
982			    (pg = TAILQ_FIRST((freeq =
983			      &pgfl->pgfl_queues[try2]))) != NULL)
984				goto gotit;
985		}
986
987		/* No pages free! */
988		goto fail;
989
990	case UVM_PGA_STRAT_ONLY:
991	case UVM_PGA_STRAT_FALLBACK:
992		/* Attempt to allocate from the specified free list. */
993		KASSERT(free_list >= 0 && free_list < VM_NFREELIST);
994		pgfl = &uvm.page_free[free_list];
995		if ((pg = TAILQ_FIRST((freeq =
996		      &pgfl->pgfl_queues[try1]))) != NULL ||
997		    (pg = TAILQ_FIRST((freeq =
998		      &pgfl->pgfl_queues[try2]))) != NULL)
999			goto gotit;
1000
1001		/* Fall back, if possible. */
1002		if (strat == UVM_PGA_STRAT_FALLBACK) {
1003			strat = UVM_PGA_STRAT_NORMAL;
1004			goto again;
1005		}
1006
1007		/* No pages free! */
1008		goto fail;
1009
1010	default:
1011		panic("uvm_pagealloc_strat: bad strat %d", strat);
1012		/* NOTREACHED */
1013	}
1014
1015 gotit:
1016	TAILQ_REMOVE(freeq, pg, pageq);
1017	uvmexp.free--;
1018
1019	/* update zero'd page count */
1020	if (pg->flags & PG_ZERO)
1021		uvmexp.zeropages--;
1022
1023	/*
1024	 * update allocation statistics and remember if we have to
1025	 * zero the page
1026	 */
1027	if (flags & UVM_PGA_ZERO) {
1028		if (pg->flags & PG_ZERO) {
1029			uvmexp.pga_zerohit++;
1030			zeroit = 0;
1031		} else {
1032			uvmexp.pga_zeromiss++;
1033			zeroit = 1;
1034		}
1035	}
1036
1037	uvm_unlock_fpageq(s);		/* unlock free page queue */
1038
1039	pg->offset = off;
1040	pg->uobject = obj;
1041	pg->uanon = anon;
1042	pg->flags = PG_BUSY|PG_CLEAN|PG_FAKE;
1043	pg->version++;
1044	if (anon) {
1045		anon->u.an_page = pg;
1046		pg->pqflags = PQ_ANON;
1047#ifdef UBC
1048		uvm_pgcnt_anon++;
1049#endif
1050	} else {
1051		if (obj)
1052			uvm_pageinsert(pg);
1053		pg->pqflags = 0;
1054	}
1055#if defined(UVM_PAGE_TRKOWN)
1056	pg->owner_tag = NULL;
1057#endif
1058	UVM_PAGE_OWN(pg, "new alloc");
1059
1060	if (flags & UVM_PGA_ZERO) {
1061		/*
1062		 * A zero'd page is not clean.  If we got a page not already
1063		 * zero'd, then we have to zero it ourselves.
1064		 */
1065		pg->flags &= ~PG_CLEAN;
1066		if (zeroit)
1067			pmap_zero_page(pg);
1068	}
1069
1070	UVMHIST_LOG(pghist, "allocated pg %p/%llx", pg,
1071	    (long long)VM_PAGE_TO_PHYS(pg), 0, 0);
1072	return(pg);
1073
1074 fail:
1075	uvm_unlock_fpageq(s);
1076	UVMHIST_LOG(pghist, "failed!", 0, 0, 0, 0);
1077	return (NULL);
1078}
1079
1080/*
1081 * uvm_pagerealloc: reallocate a page from one object to another
1082 *
1083 * => both objects must be locked
1084 */
1085
1086void
1087uvm_pagerealloc(pg, newobj, newoff)
1088	struct vm_page *pg;
1089	struct uvm_object *newobj;
1090	voff_t newoff;
1091{
1092
1093	UVMHIST_FUNC("uvm_pagerealloc"); UVMHIST_CALLED(pghist);
1094
1095	/*
1096	 * remove it from the old object
1097	 */
1098
1099	if (pg->uobject) {
1100		uvm_pageremove(pg);
1101	}
1102
1103	/*
1104	 * put it in the new object
1105	 */
1106
1107	if (newobj) {
1108		pg->uobject = newobj;
1109		pg->offset = newoff;
1110		pg->version++;
1111		uvm_pageinsert(pg);
1112	}
1113}
1114
1115
1116/*
1117 * uvm_pagefree: free page
1118 *
1119 * => erase page's identity (i.e. remove from hash/object)
1120 * => put page on free list
1121 * => caller must lock owning object (either anon or uvm_object)
1122 * => caller must lock page queues
1123 * => assumes all valid mappings of pg are gone
1124 */
1125
1126void
1127uvm_pagefree(pg)
1128	struct vm_page *pg;
1129{
1130	int s;
1131	int saved_loan_count = pg->loan_count;
1132	UVMHIST_FUNC("uvm_pagefree"); UVMHIST_CALLED(pghist);
1133
1134#ifdef DEBUG
1135	if (pg->uobject == (void *)0xdeadbeef &&
1136	    pg->uanon == (void *)0xdeadbeef) {
1137		panic("uvm_pagefree: freeing free page %p", pg);
1138	}
1139#endif
1140
1141	UVMHIST_LOG(pghist, "freeing pg %p/%llx", pg,
1142	    (long long)VM_PAGE_TO_PHYS(pg), 0, 0);
1143
1144	/*
1145	 * if the page was an object page (and thus "TABLED"), remove it
1146	 * from the object.
1147	 */
1148
1149	if (pg->flags & PG_TABLED) {
1150
1151		/*
1152		 * if the object page is on loan we are going to drop ownership.
1153		 * it is possible that an anon will take over as owner for this
1154		 * page later on.   the anon will want a !PG_CLEAN page so that
1155		 * it knows it needs to allocate swap if it wants to page the
1156		 * page out.
1157		 */
1158
1159		if (saved_loan_count)
1160			pg->flags &= ~PG_CLEAN;	/* in case an anon takes over */
1161		uvm_pageremove(pg);
1162
1163		/*
1164		 * if our page was on loan, then we just lost control over it
1165		 * (in fact, if it was loaned to an anon, the anon may have
1166		 * already taken over ownership of the page by now and thus
1167		 * changed the loan_count [e.g. in uvmfault_anonget()]) we just
1168		 * return (when the last loan is dropped, then the page can be
1169		 * freed by whatever was holding the last loan).
1170		 */
1171
1172		if (saved_loan_count)
1173			return;
1174	} else if (saved_loan_count && (pg->pqflags & PQ_ANON)) {
1175
1176		/*
1177		 * if our page is owned by an anon and is loaned out to the
1178		 * kernel then we just want to drop ownership and return.
1179		 * the kernel must free the page when all its loans clear ...
1180		 * note that the kernel can't change the loan status of our
1181		 * page as long as we are holding PQ lock.
1182		 */
1183
1184		pg->pqflags &= ~PQ_ANON;
1185		pg->uanon = NULL;
1186		return;
1187	}
1188	KASSERT(saved_loan_count == 0);
1189
1190	/*
1191	 * now remove the page from the queues
1192	 */
1193
1194	if (pg->pqflags & PQ_ACTIVE) {
1195		TAILQ_REMOVE(&uvm.page_active, pg, pageq);
1196		pg->pqflags &= ~PQ_ACTIVE;
1197		uvmexp.active--;
1198	}
1199	if (pg->pqflags & PQ_INACTIVE) {
1200		if (pg->pqflags & PQ_SWAPBACKED)
1201			TAILQ_REMOVE(&uvm.page_inactive_swp, pg, pageq);
1202		else
1203			TAILQ_REMOVE(&uvm.page_inactive_obj, pg, pageq);
1204		pg->pqflags &= ~PQ_INACTIVE;
1205		uvmexp.inactive--;
1206	}
1207
1208	/*
1209	 * if the page was wired, unwire it now.
1210	 */
1211
1212	if (pg->wire_count) {
1213		pg->wire_count = 0;
1214		uvmexp.wired--;
1215	}
1216#ifdef UBC
1217	if (pg->uanon) {
1218		uvm_pgcnt_anon--;
1219	}
1220#endif
1221
1222	/*
1223	 * and put on free queue
1224	 */
1225
1226	pg->flags &= ~PG_ZERO;
1227
1228	s = uvm_lock_fpageq();
1229	TAILQ_INSERT_TAIL(&uvm.page_free[
1230	    uvm_page_lookup_freelist(pg)].pgfl_queues[PGFL_UNKNOWN], pg, pageq);
1231	pg->pqflags = PQ_FREE;
1232#ifdef DEBUG
1233	pg->uobject = (void *)0xdeadbeef;
1234	pg->offset = 0xdeadbeef;
1235	pg->uanon = (void *)0xdeadbeef;
1236#endif
1237	uvmexp.free++;
1238
1239	if (uvmexp.zeropages < UVM_PAGEZERO_TARGET)
1240		uvm.page_idle_zero = vm_page_zero_enable;
1241
1242	uvm_unlock_fpageq(s);
1243}
1244
1245/*
1246 * uvm_page_unbusy: unbusy an array of pages.
1247 *
1248 * => pages must either all belong to the same object, or all belong to anons.
1249 * => if pages are object-owned, object must be locked.
1250 * => if pages are anon-owned, anons must be unlockd and have 0 refcount.
1251 */
1252
1253void
1254uvm_page_unbusy(pgs, npgs)
1255	struct vm_page **pgs;
1256	int npgs;
1257{
1258	struct vm_page *pg;
1259	struct uvm_object *uobj;
1260	int i;
1261	UVMHIST_FUNC("uvm_page_unbusy"); UVMHIST_CALLED(pdhist);
1262
1263	for (i = 0; i < npgs; i++) {
1264		pg = pgs[i];
1265
1266		if (pg == NULL || pg == PGO_DONTCARE) {
1267			continue;
1268		}
1269		if (pg->flags & PG_WANTED) {
1270			wakeup(pg);
1271		}
1272		if (pg->flags & PG_RELEASED) {
1273			UVMHIST_LOG(pdhist, "releasing pg %p", pg,0,0,0);
1274			uobj = pg->uobject;
1275			if (uobj != NULL) {
1276				uobj->pgops->pgo_releasepg(pg, NULL);
1277			} else {
1278				pg->flags &= ~(PG_BUSY);
1279				UVM_PAGE_OWN(pg, NULL);
1280				uvm_anfree(pg->uanon);
1281			}
1282		} else {
1283			UVMHIST_LOG(pdhist, "unbusying pg %p", pg,0,0,0);
1284			pg->flags &= ~(PG_WANTED|PG_BUSY);
1285			UVM_PAGE_OWN(pg, NULL);
1286		}
1287	}
1288}
1289
1290#if defined(UVM_PAGE_TRKOWN)
1291/*
1292 * uvm_page_own: set or release page ownership
1293 *
1294 * => this is a debugging function that keeps track of who sets PG_BUSY
1295 *	and where they do it.   it can be used to track down problems
1296 *	such a process setting "PG_BUSY" and never releasing it.
1297 * => page's object [if any] must be locked
1298 * => if "tag" is NULL then we are releasing page ownership
1299 */
1300void
1301uvm_page_own(pg, tag)
1302	struct vm_page *pg;
1303	char *tag;
1304{
1305	/* gain ownership? */
1306	if (tag) {
1307		if (pg->owner_tag) {
1308			printf("uvm_page_own: page %p already owned "
1309			    "by proc %d [%s]\n", pg,
1310			     pg->owner, pg->owner_tag);
1311			panic("uvm_page_own");
1312		}
1313		pg->owner = (curproc) ? curproc->p_pid :  (pid_t) -1;
1314		pg->owner_tag = tag;
1315		return;
1316	}
1317
1318	/* drop ownership */
1319	if (pg->owner_tag == NULL) {
1320		printf("uvm_page_own: dropping ownership of an non-owned "
1321		    "page (%p)\n", pg);
1322		panic("uvm_page_own");
1323	}
1324	pg->owner_tag = NULL;
1325	return;
1326}
1327#endif
1328
1329/*
1330 * uvm_pageidlezero: zero free pages while the system is idle.
1331 *
1332 * => we do at least one iteration per call, if we are below the target.
1333 * => we loop until we either reach the target or whichqs indicates that
1334 *	there is a process ready to run.
1335 */
1336void
1337uvm_pageidlezero()
1338{
1339	struct vm_page *pg;
1340	struct pgfreelist *pgfl;
1341	int free_list, s;
1342	UVMHIST_FUNC("uvm_pageidlezero"); UVMHIST_CALLED(pghist);
1343
1344	do {
1345		s = uvm_lock_fpageq();
1346
1347		if (uvmexp.zeropages >= UVM_PAGEZERO_TARGET) {
1348			uvm.page_idle_zero = FALSE;
1349			uvm_unlock_fpageq(s);
1350			return;
1351		}
1352
1353		for (free_list = 0; free_list < VM_NFREELIST; free_list++) {
1354			pgfl = &uvm.page_free[free_list];
1355			if ((pg = TAILQ_FIRST(&pgfl->pgfl_queues[
1356			    PGFL_UNKNOWN])) != NULL)
1357				break;
1358		}
1359
1360		if (pg == NULL) {
1361			/*
1362			 * No non-zero'd pages; don't bother trying again
1363			 * until we know we have non-zero'd pages free.
1364			 */
1365			uvm.page_idle_zero = FALSE;
1366			uvm_unlock_fpageq(s);
1367			return;
1368		}
1369
1370		TAILQ_REMOVE(&pgfl->pgfl_queues[PGFL_UNKNOWN], pg, pageq);
1371		uvmexp.free--;
1372		uvm_unlock_fpageq(s);
1373
1374#ifdef PMAP_PAGEIDLEZERO
1375		if (PMAP_PAGEIDLEZERO(pg) == FALSE) {
1376			/*
1377			 * The machine-dependent code detected some
1378			 * reason for us to abort zeroing pages,
1379			 * probably because there is a process now
1380			 * ready to run.
1381			 */
1382			s = uvm_lock_fpageq();
1383			TAILQ_INSERT_HEAD(&pgfl->pgfl_queues[PGFL_UNKNOWN],
1384			    pg, pageq);
1385			uvmexp.free++;
1386			uvmexp.zeroaborts++;
1387			uvm_unlock_fpageq(s);
1388			return;
1389		}
1390#else
1391		/*
1392		 * XXX This will toast the cache unless the pmap_zero_page()
1393		 * XXX implementation does uncached access.
1394		 */
1395		pmap_zero_page(pg);
1396#endif
1397		pg->flags |= PG_ZERO;
1398
1399		s = uvm_lock_fpageq();
1400		TAILQ_INSERT_HEAD(&pgfl->pgfl_queues[PGFL_ZEROS], pg, pageq);
1401		uvmexp.free++;
1402		uvmexp.zeropages++;
1403		uvm_unlock_fpageq(s);
1404	} while (whichqs == 0);
1405}
1406