vm_object.c revision 28992
1/*
2 * Copyright (c) 1991, 1993
3 *	The Regents of the University of California.  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_object.c	8.5 (Berkeley) 3/22/94
37 *
38 *
39 * Copyright (c) 1987, 1990 Carnegie-Mellon University.
40 * All rights reserved.
41 *
42 * Authors: Avadis Tevanian, Jr., Michael Wayne Young
43 *
44 * Permission to use, copy, modify and distribute this software and
45 * its documentation is hereby granted, provided that both the copyright
46 * notice and this permission notice appear in all copies of the
47 * software, derivative works or modified versions, and any portions
48 * thereof, and that both notices appear in supporting documentation.
49 *
50 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
51 * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
52 * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
53 *
54 * Carnegie Mellon requests users of this software to return to
55 *
56 *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
57 *  School of Computer Science
58 *  Carnegie Mellon University
59 *  Pittsburgh PA 15213-3890
60 *
61 * any improvements or extensions that they make and grant Carnegie the
62 * rights to redistribute these changes.
63 *
64 * $Id: vm_object.c,v 1.96 1997/09/01 02:55:48 bde Exp $
65 */
66
67/*
68 *	Virtual memory object module.
69 */
70
71#include <sys/param.h>
72#include <sys/systm.h>
73#include <sys/proc.h>		/* for curproc, pageproc */
74#include <sys/malloc.h>
75#include <sys/vnode.h>
76#include <sys/vmmeter.h>
77#include <sys/mman.h>
78
79#include <vm/vm.h>
80#include <vm/vm_param.h>
81#include <vm/vm_prot.h>
82#include <sys/lock.h>
83#include <vm/pmap.h>
84#include <vm/vm_map.h>
85#include <vm/vm_object.h>
86#include <vm/vm_page.h>
87#include <vm/vm_pageout.h>
88#include <vm/vm_pager.h>
89#include <vm/swap_pager.h>
90#include <vm/vm_kern.h>
91#include <vm/vm_extern.h>
92
93static void	vm_object_qcollapse __P((vm_object_t object));
94#ifdef not_used
95static void	vm_object_deactivate_pages __P((vm_object_t));
96#endif
97static void	vm_object_terminate __P((vm_object_t));
98static void	vm_object_cache_trim __P((void));
99
100/*
101 *	Virtual memory objects maintain the actual data
102 *	associated with allocated virtual memory.  A given
103 *	page of memory exists within exactly one object.
104 *
105 *	An object is only deallocated when all "references"
106 *	are given up.  Only one "reference" to a given
107 *	region of an object should be writeable.
108 *
109 *	Associated with each object is a list of all resident
110 *	memory pages belonging to that object; this list is
111 *	maintained by the "vm_page" module, and locked by the object's
112 *	lock.
113 *
114 *	Each object also records a "pager" routine which is
115 *	used to retrieve (and store) pages to the proper backing
116 *	storage.  In addition, objects may be backed by other
117 *	objects from which they were virtual-copied.
118 *
119 *	The only items within the object structure which are
120 *	modified after time of creation are:
121 *		reference count		locked by object's lock
122 *		pager routine		locked by object's lock
123 *
124 */
125
126int vm_object_cache_max;
127struct object_q vm_object_cached_list;
128static int vm_object_cached;		/* size of cached list */
129struct object_q vm_object_list;
130struct simplelock vm_object_list_lock;
131static long vm_object_count;		/* count of all objects */
132vm_object_t kernel_object;
133vm_object_t kmem_object;
134static struct vm_object kernel_object_store;
135static struct vm_object kmem_object_store;
136extern int vm_pageout_page_count;
137
138static long object_collapses;
139static long object_bypasses;
140static int next_index;
141
142void
143_vm_object_allocate(type, size, object)
144	objtype_t type;
145	vm_size_t size;
146	register vm_object_t object;
147{
148	TAILQ_INIT(&object->memq);
149	TAILQ_INIT(&object->shadow_head);
150
151	object->type = type;
152	object->size = size;
153	object->ref_count = 1;
154	object->flags = 0;
155	object->behavior = OBJ_NORMAL;
156	object->paging_in_progress = 0;
157	object->resident_page_count = 0;
158	object->shadow_count = 0;
159	object->pg_color = next_index;
160	next_index = (next_index + PQ_PRIME1) & PQ_L2_MASK;
161	object->handle = NULL;
162	object->paging_offset = (vm_ooffset_t) 0;
163	object->backing_object = NULL;
164	object->backing_object_offset = (vm_ooffset_t) 0;
165	object->page_hint = NULL;
166
167	object->last_read = 0;
168
169	TAILQ_INSERT_TAIL(&vm_object_list, object, object_list);
170	vm_object_count++;
171}
172
173/*
174 *	vm_object_init:
175 *
176 *	Initialize the VM objects module.
177 */
178void
179vm_object_init()
180{
181	TAILQ_INIT(&vm_object_cached_list);
182	TAILQ_INIT(&vm_object_list);
183	simple_lock_init(&vm_object_list_lock);
184	vm_object_count = 0;
185
186	vm_object_cache_max = 84;
187	if (cnt.v_page_count > 1000)
188		vm_object_cache_max += (cnt.v_page_count - 1000) / 4;
189
190	kernel_object = &kernel_object_store;
191	_vm_object_allocate(OBJT_DEFAULT, OFF_TO_IDX(VM_MAX_KERNEL_ADDRESS - VM_MIN_KERNEL_ADDRESS),
192	    kernel_object);
193
194	kmem_object = &kmem_object_store;
195	_vm_object_allocate(OBJT_DEFAULT, OFF_TO_IDX(VM_MAX_KERNEL_ADDRESS - VM_MIN_KERNEL_ADDRESS),
196	    kmem_object);
197}
198
199/*
200 *	vm_object_allocate:
201 *
202 *	Returns a new object with the given size.
203 */
204
205vm_object_t
206vm_object_allocate(type, size)
207	objtype_t type;
208	vm_size_t size;
209{
210	register vm_object_t result;
211
212	result = (vm_object_t)
213	    malloc((u_long) sizeof *result, M_VMOBJ, M_WAITOK);
214
215
216	_vm_object_allocate(type, size, result);
217
218	return (result);
219}
220
221
222/*
223 *	vm_object_reference:
224 *
225 *	Gets another reference to the given object.
226 */
227void
228vm_object_reference(object)
229	register vm_object_t object;
230{
231	if (object == NULL)
232		return;
233
234	if (object->ref_count == 0) {
235		if ((object->flags & OBJ_CANPERSIST) == 0)
236			panic("vm_object_reference: non-persistent object with 0 ref_count");
237		TAILQ_REMOVE(&vm_object_cached_list, object, cached_list);
238		vm_object_cached--;
239	}
240	object->ref_count++;
241}
242
243/*
244 *	vm_object_deallocate:
245 *
246 *	Release a reference to the specified object,
247 *	gained either through a vm_object_allocate
248 *	or a vm_object_reference call.  When all references
249 *	are gone, storage associated with this object
250 *	may be relinquished.
251 *
252 *	No object may be locked.
253 */
254void
255vm_object_deallocate(object)
256	vm_object_t object;
257{
258	vm_object_t temp;
259
260	while (object != NULL) {
261
262		if (object->ref_count == 0)
263			panic("vm_object_deallocate: object deallocated too many times");
264
265		/*
266		 * Lose the reference
267		 */
268		object->ref_count--;
269		if (object->ref_count != 0) {
270			if ((object->ref_count == 1) &&
271			    (object->handle == NULL) &&
272			    (object->type == OBJT_DEFAULT ||
273			     object->type == OBJT_SWAP)) {
274				vm_object_t robject;
275				robject = TAILQ_FIRST(&object->shadow_head);
276				if ((robject != NULL) &&
277				    (robject->handle == NULL) &&
278				    (robject->type == OBJT_DEFAULT ||
279				     robject->type == OBJT_SWAP)) {
280					int s;
281					robject->ref_count += 2;
282					object->ref_count += 2;
283
284					do {
285						s = splvm();
286						while (robject->paging_in_progress) {
287							robject->flags |= OBJ_PIPWNT;
288							tsleep(robject, PVM, "objde1", 0);
289						}
290
291						while (object->paging_in_progress) {
292							object->flags |= OBJ_PIPWNT;
293							tsleep(object, PVM, "objde2", 0);
294						}
295						splx(s);
296
297					} while( object->paging_in_progress || robject->paging_in_progress);
298
299					object->ref_count -= 2;
300					robject->ref_count -= 2;
301					if( robject->ref_count == 0) {
302						robject->ref_count += 1;
303						object = robject;
304						continue;
305					}
306					vm_object_collapse(robject);
307					return;
308				}
309			}
310			/*
311			 * If there are still references, then we are done.
312			 */
313			return;
314		}
315
316		if (object->type == OBJT_VNODE) {
317			struct vnode *vp = object->handle;
318
319			vp->v_flag &= ~VTEXT;
320		}
321
322		/*
323		 * See if this object can persist and has some resident
324		 * pages.  If so, enter it in the cache.
325		 */
326		if (object->flags & OBJ_CANPERSIST) {
327			if (object->resident_page_count != 0) {
328#if 0
329				vm_object_page_clean(object, 0, 0 ,TRUE, TRUE);
330#endif
331				TAILQ_INSERT_TAIL(&vm_object_cached_list, object,
332				    cached_list);
333				vm_object_cached++;
334
335				vm_object_cache_trim();
336				return;
337			} else {
338				object->flags &= ~OBJ_CANPERSIST;
339			}
340		}
341
342		/*
343		 * Make sure no one uses us.
344		 */
345		object->flags |= OBJ_DEAD;
346
347		temp = object->backing_object;
348		if (temp) {
349			TAILQ_REMOVE(&temp->shadow_head, object, shadow_list);
350			--temp->shadow_count;
351		}
352		vm_object_terminate(object);
353		/* unlocks and deallocates object */
354		object = temp;
355	}
356}
357
358/*
359 *	vm_object_terminate actually destroys the specified object, freeing
360 *	up all previously used resources.
361 *
362 *	The object must be locked.
363 */
364static void
365vm_object_terminate(object)
366	register vm_object_t object;
367{
368	register vm_page_t p;
369	int s;
370
371	if (object->flags & OBJ_VFS_REF)
372		panic("vm_object_deallocate: freeing VFS_REF'ed object");
373
374	/*
375	 * wait for the pageout daemon to be done with the object
376	 */
377	s = splvm();
378	while (object->paging_in_progress) {
379		object->flags |= OBJ_PIPWNT;
380		tsleep(object, PVM, "objtrm", 0);
381	}
382	splx(s);
383
384	if (object->paging_in_progress != 0)
385		panic("vm_object_deallocate: pageout in progress");
386
387	/*
388	 * Clean and free the pages, as appropriate. All references to the
389	 * object are gone, so we don't need to lock it.
390	 */
391	if (object->type == OBJT_VNODE) {
392		struct vnode *vp = object->handle;
393		struct proc *p = curproc;	/* XXX */
394		int waslocked;
395
396		waslocked = VOP_ISLOCKED(vp);
397		if (!waslocked)
398			vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
399		vm_object_page_clean(object, 0, 0, TRUE, FALSE);
400		vinvalbuf(vp, V_SAVE, NOCRED, NULL, 0, 0);
401		if (!waslocked)
402			VOP_UNLOCK(vp, 0, p);
403	}
404
405	/*
406	 * Now free the pages. For internal objects, this also removes them
407	 * from paging queues.
408	 */
409	while ((p = TAILQ_FIRST(&object->memq)) != NULL) {
410		if (p->busy || (p->flags & PG_BUSY))
411			printf("vm_object_terminate: freeing busy page\n");
412		PAGE_WAKEUP(p);
413		vm_page_free(p);
414		cnt.v_pfree++;
415	}
416
417	/*
418	 * Let the pager know object is dead.
419	 */
420	vm_pager_deallocate(object);
421
422	simple_lock(&vm_object_list_lock);
423	TAILQ_REMOVE(&vm_object_list, object, object_list);
424	vm_object_count--;
425	simple_unlock(&vm_object_list_lock);
426
427	wakeup(object);
428
429	/*
430	 * Free the space for the object.
431	 */
432	free((caddr_t) object, M_VMOBJ);
433}
434
435/*
436 *	vm_object_page_clean
437 *
438 *	Clean all dirty pages in the specified range of object.
439 *	Leaves page on whatever queue it is currently on.
440 *
441 *	Odd semantics: if start == end, we clean everything.
442 *
443 *	The object must be locked.
444 */
445
446void
447vm_object_page_clean(object, start, end, syncio, lockflag)
448	vm_object_t object;
449	vm_pindex_t start;
450	vm_pindex_t end;
451	boolean_t syncio;
452	boolean_t lockflag;
453{
454	register vm_page_t p, np, tp;
455	register vm_offset_t tstart, tend;
456	vm_pindex_t pi;
457	int s;
458	struct vnode *vp;
459	int runlen;
460	int maxf;
461	int chkb;
462	int maxb;
463	int i;
464	vm_page_t maf[vm_pageout_page_count];
465	vm_page_t mab[vm_pageout_page_count];
466	vm_page_t ma[vm_pageout_page_count];
467	struct proc *pproc = curproc;	/* XXX */
468
469	if (object->type != OBJT_VNODE ||
470		(object->flags & OBJ_MIGHTBEDIRTY) == 0)
471		return;
472
473	vp = object->handle;
474
475	if (lockflag)
476		vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, pproc);
477	object->flags |= OBJ_CLEANING;
478
479	tstart = start;
480	if (end == 0) {
481		tend = object->size;
482	} else {
483		tend = end;
484	}
485	if ((tstart == 0) && (tend == object->size)) {
486		object->flags &= ~(OBJ_WRITEABLE|OBJ_MIGHTBEDIRTY);
487	}
488	for(p = TAILQ_FIRST(&object->memq); p; p = TAILQ_NEXT(p, listq))
489		p->flags |= PG_CLEANCHK;
490
491rescan:
492	for(p = TAILQ_FIRST(&object->memq); p; p = np) {
493		np = TAILQ_NEXT(p, listq);
494
495		pi = p->pindex;
496		if (((p->flags & PG_CLEANCHK) == 0) ||
497			(pi < tstart) || (pi >= tend) ||
498			(p->valid == 0) ||
499			((p->queue - p->pc) == PQ_CACHE)) {
500			p->flags &= ~PG_CLEANCHK;
501			continue;
502		}
503
504		vm_page_test_dirty(p);
505		if ((p->dirty & p->valid) == 0) {
506			p->flags &= ~PG_CLEANCHK;
507			continue;
508		}
509
510		s = splvm();
511		if ((p->flags & PG_BUSY) || p->busy) {
512			p->flags |= PG_WANTED|PG_REFERENCED;
513			tsleep(p, PVM, "vpcwai", 0);
514			splx(s);
515			goto rescan;
516		}
517		splx(s);
518
519		s = splvm();
520		maxf = 0;
521		for(i=1;i<vm_pageout_page_count;i++) {
522			if (tp = vm_page_lookup(object, pi + i)) {
523				if ((tp->flags & PG_BUSY) ||
524					(tp->flags & PG_CLEANCHK) == 0)
525					break;
526				if((tp->queue - tp->pc) == PQ_CACHE) {
527					tp->flags &= ~PG_CLEANCHK;
528					break;
529				}
530				vm_page_test_dirty(tp);
531				if ((tp->dirty & tp->valid) == 0) {
532					tp->flags &= ~PG_CLEANCHK;
533					break;
534				}
535				maf[ i - 1 ] = tp;
536				maxf++;
537				continue;
538			}
539			break;
540		}
541
542		maxb = 0;
543		chkb = vm_pageout_page_count -  maxf;
544		if (chkb) {
545			for(i = 1; i < chkb;i++) {
546				if (tp = vm_page_lookup(object, pi - i)) {
547					if ((tp->flags & PG_BUSY) ||
548						(tp->flags & PG_CLEANCHK) == 0)
549						break;
550					if((tp->queue - tp->pc) == PQ_CACHE) {
551						tp->flags &= ~PG_CLEANCHK;
552						break;
553					}
554					vm_page_test_dirty(tp);
555					if ((tp->dirty & tp->valid) == 0) {
556						tp->flags &= ~PG_CLEANCHK;
557						break;
558					}
559					mab[ i - 1 ] = tp;
560					maxb++;
561					continue;
562				}
563				break;
564			}
565		}
566
567		for(i=0;i<maxb;i++) {
568			int index = (maxb - i) - 1;
569			ma[index] = mab[i];
570			ma[index]->flags |= PG_BUSY;
571			ma[index]->flags &= ~PG_CLEANCHK;
572			vm_page_protect(ma[index], VM_PROT_READ);
573		}
574		vm_page_protect(p, VM_PROT_READ);
575		p->flags |= PG_BUSY;
576		p->flags &= ~PG_CLEANCHK;
577		ma[maxb] = p;
578		for(i=0;i<maxf;i++) {
579			int index = (maxb + i) + 1;
580			ma[index] = maf[i];
581			ma[index]->flags |= PG_BUSY;
582			ma[index]->flags &= ~PG_CLEANCHK;
583			vm_page_protect(ma[index], VM_PROT_READ);
584		}
585		runlen = maxb + maxf + 1;
586		splx(s);
587		vm_pageout_flush(ma, runlen, 0);
588		goto rescan;
589	}
590
591	VOP_FSYNC(vp, NULL, syncio, curproc);
592
593	if (lockflag)
594		VOP_UNLOCK(vp, 0, pproc);
595	object->flags &= ~OBJ_CLEANING;
596	return;
597}
598
599#ifdef not_used
600/* XXX I cannot tell if this should be an exported symbol */
601/*
602 *	vm_object_deactivate_pages
603 *
604 *	Deactivate all pages in the specified object.  (Keep its pages
605 *	in memory even though it is no longer referenced.)
606 *
607 *	The object must be locked.
608 */
609static void
610vm_object_deactivate_pages(object)
611	register vm_object_t object;
612{
613	register vm_page_t p, next;
614
615	for (p = TAILQ_FIRST(&object->memq); p != NULL; p = next) {
616		next = TAILQ_NEXT(p, listq);
617		vm_page_deactivate(p);
618	}
619}
620#endif
621
622/*
623 *	Trim the object cache to size.
624 */
625static void
626vm_object_cache_trim()
627{
628	register vm_object_t object;
629
630	while (vm_object_cached > vm_object_cache_max) {
631		object = TAILQ_FIRST(&vm_object_cached_list);
632
633		vm_object_reference(object);
634		pager_cache(object, FALSE);
635	}
636}
637
638
639/*
640 *	vm_object_pmap_copy:
641 *
642 *	Makes all physical pages in the specified
643 *	object range copy-on-write.  No writeable
644 *	references to these pages should remain.
645 *
646 *	The object must *not* be locked.
647 */
648void
649vm_object_pmap_copy(object, start, end)
650	register vm_object_t object;
651	register vm_pindex_t start;
652	register vm_pindex_t end;
653{
654	register vm_page_t p;
655
656	if (object == NULL || (object->flags & OBJ_WRITEABLE) == 0)
657		return;
658
659	for (p = TAILQ_FIRST(&object->memq);
660		p != NULL;
661		p = TAILQ_NEXT(p, listq)) {
662		vm_page_protect(p, VM_PROT_READ);
663	}
664
665	object->flags &= ~OBJ_WRITEABLE;
666}
667
668/*
669 *	vm_object_pmap_remove:
670 *
671 *	Removes all physical pages in the specified
672 *	object range from all physical maps.
673 *
674 *	The object must *not* be locked.
675 */
676void
677vm_object_pmap_remove(object, start, end)
678	register vm_object_t object;
679	register vm_pindex_t start;
680	register vm_pindex_t end;
681{
682	register vm_page_t p;
683	if (object == NULL)
684		return;
685	for (p = TAILQ_FIRST(&object->memq);
686		p != NULL;
687		p = TAILQ_NEXT(p, listq)) {
688		if (p->pindex >= start && p->pindex < end)
689			vm_page_protect(p, VM_PROT_NONE);
690	}
691	if ((start == 0) && (object->size == end))
692		object->flags &= ~OBJ_WRITEABLE;
693}
694
695/*
696 *	vm_object_madvise:
697 *
698 *	Implements the madvise function at the object/page level.
699 */
700void
701vm_object_madvise(object, pindex, count, advise)
702	vm_object_t object;
703	vm_pindex_t pindex;
704	int count;
705	int advise;
706{
707	int s;
708	vm_pindex_t end, tpindex;
709	vm_object_t tobject;
710	vm_page_t m;
711
712	if (object == NULL)
713		return;
714
715	end = pindex + count;
716
717	for (; pindex < end; pindex += 1) {
718
719relookup:
720		tobject = object;
721		tpindex = pindex;
722shadowlookup:
723		m = vm_page_lookup(tobject, tpindex);
724		if (m == NULL) {
725			if (tobject->type != OBJT_DEFAULT) {
726				continue;
727			}
728
729			tobject = tobject->backing_object;
730			if ((tobject == NULL) || (tobject->ref_count != 1)) {
731				continue;
732			}
733			tpindex += OFF_TO_IDX(tobject->backing_object_offset);
734			goto shadowlookup;
735		}
736
737		/*
738		 * If the page is busy or not in a normal active state,
739		 * we skip it.  Things can break if we mess with pages
740		 * in any of the below states.
741		 */
742		if (m->hold_count || m->wire_count ||
743			m->valid != VM_PAGE_BITS_ALL) {
744			continue;
745		}
746
747		if (m->busy || (m->flags & PG_BUSY)) {
748			s = splvm();
749			if (m->busy || (m->flags & PG_BUSY)) {
750				m->flags |= PG_WANTED;
751				tsleep(m, PVM, "madvpw", 0);
752			}
753			splx(s);
754			goto relookup;
755		}
756
757		if (advise == MADV_WILLNEED) {
758			if (m->queue != PQ_ACTIVE)
759				vm_page_activate(m);
760		} else if (advise == MADV_DONTNEED) {
761			vm_page_deactivate(m);
762		} else if (advise == MADV_FREE) {
763			pmap_clear_modify(VM_PAGE_TO_PHYS(m));
764			m->dirty = 0;
765			/*
766			 * Force a demand zero if attempt to read from swap.
767			 * We currently don't handle vnode files correctly,
768			 * and will reread stale contents unnecessarily.
769			 */
770			if (object->type == OBJT_SWAP)
771				swap_pager_dmzspace(tobject, m->pindex, 1);
772		}
773	}
774}
775
776/*
777 *	vm_object_shadow:
778 *
779 *	Create a new object which is backed by the
780 *	specified existing object range.  The source
781 *	object reference is deallocated.
782 *
783 *	The new object and offset into that object
784 *	are returned in the source parameters.
785 */
786
787void
788vm_object_shadow(object, offset, length)
789	vm_object_t *object;	/* IN/OUT */
790	vm_ooffset_t *offset;	/* IN/OUT */
791	vm_size_t length;
792{
793	register vm_object_t source;
794	register vm_object_t result;
795
796	source = *object;
797
798	/*
799	 * Allocate a new object with the given length
800	 */
801
802	if ((result = vm_object_allocate(OBJT_DEFAULT, length)) == NULL)
803		panic("vm_object_shadow: no object for shadowing");
804
805	/*
806	 * The new object shadows the source object, adding a reference to it.
807	 * Our caller changes his reference to point to the new object,
808	 * removing a reference to the source object.  Net result: no change
809	 * of reference count.
810	 */
811	result->backing_object = source;
812	if (source) {
813		TAILQ_INSERT_TAIL(&source->shadow_head, result, shadow_list);
814		++source->shadow_count;
815	}
816
817	/*
818	 * Store the offset into the source object, and fix up the offset into
819	 * the new object.
820	 */
821
822	result->backing_object_offset = *offset;
823
824	/*
825	 * Return the new things
826	 */
827
828	*offset = 0;
829	*object = result;
830}
831
832
833/*
834 * this version of collapse allows the operation to occur earlier and
835 * when paging_in_progress is true for an object...  This is not a complete
836 * operation, but should plug 99.9% of the rest of the leaks.
837 */
838static void
839vm_object_qcollapse(object)
840	register vm_object_t object;
841{
842	register vm_object_t backing_object;
843	register vm_pindex_t backing_offset_index, paging_offset_index;
844	vm_pindex_t backing_object_paging_offset_index;
845	vm_pindex_t new_pindex;
846	register vm_page_t p, pp;
847	register vm_size_t size;
848
849	backing_object = object->backing_object;
850	if (backing_object->ref_count != 1)
851		return;
852
853	backing_object->ref_count += 2;
854
855	backing_offset_index = OFF_TO_IDX(object->backing_object_offset);
856	backing_object_paging_offset_index = OFF_TO_IDX(backing_object->paging_offset);
857	paging_offset_index = OFF_TO_IDX(object->paging_offset);
858	size = object->size;
859	p = TAILQ_FIRST(&backing_object->memq);
860	while (p) {
861		vm_page_t next;
862
863		next = TAILQ_NEXT(p, listq);
864		if ((p->flags & (PG_BUSY | PG_FICTITIOUS)) ||
865		    ((p->queue - p->pc) == PQ_CACHE) ||
866		    !p->valid || p->hold_count || p->wire_count || p->busy) {
867			p = next;
868			continue;
869		}
870		new_pindex = p->pindex - backing_offset_index;
871		if (p->pindex < backing_offset_index ||
872		    new_pindex >= size) {
873			if (backing_object->type == OBJT_SWAP)
874				swap_pager_freespace(backing_object,
875				    backing_object_paging_offset_index+p->pindex,
876				    1);
877			vm_page_protect(p, VM_PROT_NONE);
878			vm_page_free(p);
879		} else {
880			pp = vm_page_lookup(object, new_pindex);
881			if (pp != NULL || (object->type == OBJT_SWAP && vm_pager_has_page(object,
882				    paging_offset_index + new_pindex, NULL, NULL))) {
883				if (backing_object->type == OBJT_SWAP)
884					swap_pager_freespace(backing_object,
885					    backing_object_paging_offset_index + p->pindex, 1);
886				vm_page_protect(p, VM_PROT_NONE);
887				vm_page_free(p);
888			} else {
889				if (backing_object->type == OBJT_SWAP)
890					swap_pager_freespace(backing_object,
891					    backing_object_paging_offset_index + p->pindex, 1);
892				vm_page_rename(p, object, new_pindex);
893				vm_page_protect(p, VM_PROT_NONE);
894				p->dirty = VM_PAGE_BITS_ALL;
895			}
896		}
897		p = next;
898	}
899	backing_object->ref_count -= 2;
900}
901
902/*
903 *	vm_object_collapse:
904 *
905 *	Collapse an object with the object backing it.
906 *	Pages in the backing object are moved into the
907 *	parent, and the backing object is deallocated.
908 */
909void
910vm_object_collapse(object)
911	vm_object_t object;
912
913{
914	vm_object_t backing_object;
915	vm_ooffset_t backing_offset;
916	vm_size_t size;
917	vm_pindex_t new_pindex, backing_offset_index;
918	vm_page_t p, pp;
919
920	while (TRUE) {
921		/*
922		 * Verify that the conditions are right for collapse:
923		 *
924		 * The object exists and no pages in it are currently being paged
925		 * out.
926		 */
927		if (object == NULL)
928			return;
929
930		/*
931		 * Make sure there is a backing object.
932		 */
933		if ((backing_object = object->backing_object) == NULL)
934			return;
935
936		/*
937		 * we check the backing object first, because it is most likely
938		 * not collapsable.
939		 */
940		if (backing_object->handle != NULL ||
941		    (backing_object->type != OBJT_DEFAULT &&
942		     backing_object->type != OBJT_SWAP) ||
943		    (backing_object->flags & OBJ_DEAD) ||
944		    object->handle != NULL ||
945		    (object->type != OBJT_DEFAULT &&
946		     object->type != OBJT_SWAP) ||
947		    (object->flags & OBJ_DEAD)) {
948			return;
949		}
950
951		if (object->paging_in_progress != 0 ||
952		    backing_object->paging_in_progress != 0) {
953			vm_object_qcollapse(object);
954			return;
955		}
956
957		/*
958		 * We know that we can either collapse the backing object (if
959		 * the parent is the only reference to it) or (perhaps) remove
960		 * the parent's reference to it.
961		 */
962
963		backing_offset = object->backing_object_offset;
964		backing_offset_index = OFF_TO_IDX(backing_offset);
965		size = object->size;
966
967		/*
968		 * If there is exactly one reference to the backing object, we
969		 * can collapse it into the parent.
970		 */
971
972		if (backing_object->ref_count == 1) {
973
974			backing_object->flags |= OBJ_DEAD;
975			/*
976			 * We can collapse the backing object.
977			 *
978			 * Move all in-memory pages from backing_object to the
979			 * parent.  Pages that have been paged out will be
980			 * overwritten by any of the parent's pages that
981			 * shadow them.
982			 */
983
984			while ((p = TAILQ_FIRST(&backing_object->memq)) != 0) {
985
986				new_pindex = p->pindex - backing_offset_index;
987
988				/*
989				 * If the parent has a page here, or if this
990				 * page falls outside the parent, dispose of
991				 * it.
992				 *
993				 * Otherwise, move it as planned.
994				 */
995
996				if (p->pindex < backing_offset_index ||
997				    new_pindex >= size) {
998					vm_page_protect(p, VM_PROT_NONE);
999					PAGE_WAKEUP(p);
1000					vm_page_free(p);
1001				} else {
1002					pp = vm_page_lookup(object, new_pindex);
1003					if (pp != NULL || (object->type == OBJT_SWAP && vm_pager_has_page(object,
1004					    OFF_TO_IDX(object->paging_offset) + new_pindex, NULL, NULL))) {
1005						vm_page_protect(p, VM_PROT_NONE);
1006						PAGE_WAKEUP(p);
1007						vm_page_free(p);
1008					} else {
1009						vm_page_protect(p, VM_PROT_NONE);
1010						vm_page_rename(p, object, new_pindex);
1011						p->dirty = VM_PAGE_BITS_ALL;
1012					}
1013				}
1014			}
1015
1016			/*
1017			 * Move the pager from backing_object to object.
1018			 */
1019
1020			if (backing_object->type == OBJT_SWAP) {
1021				backing_object->paging_in_progress++;
1022				if (object->type == OBJT_SWAP) {
1023					object->paging_in_progress++;
1024					/*
1025					 * copy shadow object pages into ours
1026					 * and destroy unneeded pages in
1027					 * shadow object.
1028					 */
1029					swap_pager_copy(
1030					    backing_object,
1031					    OFF_TO_IDX(backing_object->paging_offset),
1032					    object,
1033					    OFF_TO_IDX(object->paging_offset),
1034					    OFF_TO_IDX(object->backing_object_offset));
1035					vm_object_pip_wakeup(object);
1036				} else {
1037					object->paging_in_progress++;
1038					/*
1039					 * move the shadow backing_object's pager data to
1040					 * "object" and convert "object" type to OBJT_SWAP.
1041					 */
1042					object->type = OBJT_SWAP;
1043					object->un_pager.swp.swp_nblocks =
1044					    backing_object->un_pager.swp.swp_nblocks;
1045					object->un_pager.swp.swp_allocsize =
1046					    backing_object->un_pager.swp.swp_allocsize;
1047					object->un_pager.swp.swp_blocks =
1048					    backing_object->un_pager.swp.swp_blocks;
1049					object->un_pager.swp.swp_poip =		/* XXX */
1050					    backing_object->un_pager.swp.swp_poip;
1051					object->paging_offset = backing_object->paging_offset + backing_offset;
1052					TAILQ_INSERT_TAIL(&swap_pager_un_object_list, object, pager_object_list);
1053
1054					/*
1055					 * Convert backing object from OBJT_SWAP to
1056					 * OBJT_DEFAULT. XXX - only the TAILQ_REMOVE is
1057					 * actually necessary.
1058					 */
1059					backing_object->type = OBJT_DEFAULT;
1060					TAILQ_REMOVE(&swap_pager_un_object_list, backing_object, pager_object_list);
1061					/*
1062					 * free unnecessary blocks
1063					 */
1064					swap_pager_freespace(object, 0,
1065						OFF_TO_IDX(object->paging_offset));
1066					vm_object_pip_wakeup(object);
1067				}
1068
1069				vm_object_pip_wakeup(backing_object);
1070			}
1071			/*
1072			 * Object now shadows whatever backing_object did.
1073			 * Note that the reference to backing_object->backing_object
1074			 * moves from within backing_object to within object.
1075			 */
1076
1077			TAILQ_REMOVE(&object->backing_object->shadow_head, object,
1078			    shadow_list);
1079			--object->backing_object->shadow_count;
1080			if (backing_object->backing_object) {
1081				TAILQ_REMOVE(&backing_object->backing_object->shadow_head,
1082				    backing_object, shadow_list);
1083				--backing_object->backing_object->shadow_count;
1084			}
1085			object->backing_object = backing_object->backing_object;
1086			if (object->backing_object) {
1087				TAILQ_INSERT_TAIL(&object->backing_object->shadow_head,
1088				    object, shadow_list);
1089				++object->backing_object->shadow_count;
1090			}
1091
1092			object->backing_object_offset += backing_object->backing_object_offset;
1093			/*
1094			 * Discard backing_object.
1095			 *
1096			 * Since the backing object has no pages, no pager left,
1097			 * and no object references within it, all that is
1098			 * necessary is to dispose of it.
1099			 */
1100
1101			TAILQ_REMOVE(&vm_object_list, backing_object,
1102			    object_list);
1103			vm_object_count--;
1104
1105			free((caddr_t) backing_object, M_VMOBJ);
1106
1107			object_collapses++;
1108		} else {
1109			/*
1110			 * If all of the pages in the backing object are
1111			 * shadowed by the parent object, the parent object no
1112			 * longer has to shadow the backing object; it can
1113			 * shadow the next one in the chain.
1114			 *
1115			 * The backing object must not be paged out - we'd have
1116			 * to check all of the paged-out pages, as well.
1117			 */
1118
1119			if (backing_object->type != OBJT_DEFAULT) {
1120				return;
1121			}
1122			/*
1123			 * Should have a check for a 'small' number of pages
1124			 * here.
1125			 */
1126
1127			for (p = TAILQ_FIRST(&backing_object->memq); p; p = TAILQ_NEXT(p, listq)) {
1128				new_pindex = p->pindex - backing_offset_index;
1129
1130				/*
1131				 * If the parent has a page here, or if this
1132				 * page falls outside the parent, keep going.
1133				 *
1134				 * Otherwise, the backing_object must be left in
1135				 * the chain.
1136				 */
1137
1138				if (p->pindex >= backing_offset_index &&
1139					new_pindex <= size) {
1140
1141					pp = vm_page_lookup(object, new_pindex);
1142
1143					if ((pp == NULL || pp->valid == 0) &&
1144				   	    !vm_pager_has_page(object, OFF_TO_IDX(object->paging_offset) + new_pindex, NULL, NULL)) {
1145						/*
1146						 * Page still needed. Can't go any
1147						 * further.
1148						 */
1149						return;
1150					}
1151				}
1152			}
1153
1154			/*
1155			 * Make the parent shadow the next object in the
1156			 * chain.  Deallocating backing_object will not remove
1157			 * it, since its reference count is at least 2.
1158			 */
1159
1160			TAILQ_REMOVE(&object->backing_object->shadow_head,
1161			    object, shadow_list);
1162			--object->backing_object->shadow_count;
1163			vm_object_reference(object->backing_object = backing_object->backing_object);
1164			if (object->backing_object) {
1165				TAILQ_INSERT_TAIL(&object->backing_object->shadow_head,
1166				    object, shadow_list);
1167				++object->backing_object->shadow_count;
1168			}
1169			object->backing_object_offset += backing_object->backing_object_offset;
1170
1171			/*
1172			 * Drop the reference count on backing_object. Since
1173			 * its ref_count was at least 2, it will not vanish;
1174			 * so we don't need to call vm_object_deallocate.
1175			 */
1176			if (backing_object->ref_count == 1)
1177				printf("should have called obj deallocate\n");
1178			backing_object->ref_count--;
1179
1180			object_bypasses++;
1181
1182		}
1183
1184		/*
1185		 * Try again with this object's new backing object.
1186		 */
1187	}
1188}
1189
1190/*
1191 *	vm_object_page_remove: [internal]
1192 *
1193 *	Removes all physical pages in the specified
1194 *	object range from the object's list of pages.
1195 *
1196 *	The object must be locked.
1197 */
1198void
1199vm_object_page_remove(object, start, end, clean_only)
1200	register vm_object_t object;
1201	register vm_pindex_t start;
1202	register vm_pindex_t end;
1203	boolean_t clean_only;
1204{
1205	register vm_page_t p, next;
1206	unsigned int size;
1207	int s;
1208
1209	if (object == NULL)
1210		return;
1211
1212	object->paging_in_progress++;
1213again:
1214	size = end - start;
1215	if (size > 4 || size >= object->size / 4) {
1216		for (p = TAILQ_FIRST(&object->memq); p != NULL; p = next) {
1217			next = TAILQ_NEXT(p, listq);
1218			if ((start <= p->pindex) && (p->pindex < end)) {
1219				if (p->wire_count != 0) {
1220					vm_page_protect(p, VM_PROT_NONE);
1221					p->valid = 0;
1222					continue;
1223				}
1224
1225				/*
1226				 * The busy flags are only cleared at
1227				 * interrupt -- minimize the spl transitions
1228				 */
1229				if ((p->flags & PG_BUSY) || p->busy) {
1230					s = splvm();
1231					if ((p->flags & PG_BUSY) || p->busy) {
1232						p->flags |= PG_WANTED;
1233						tsleep(p, PVM, "vmopar", 0);
1234						splx(s);
1235						goto again;
1236					}
1237					splx(s);
1238				}
1239
1240				if (clean_only) {
1241					vm_page_test_dirty(p);
1242					if (p->valid & p->dirty)
1243						continue;
1244				}
1245				vm_page_protect(p, VM_PROT_NONE);
1246				PAGE_WAKEUP(p);
1247				vm_page_free(p);
1248			}
1249		}
1250	} else {
1251		while (size > 0) {
1252			if ((p = vm_page_lookup(object, start)) != 0) {
1253				if (p->wire_count != 0) {
1254					p->valid = 0;
1255					vm_page_protect(p, VM_PROT_NONE);
1256					start += 1;
1257					size -= 1;
1258					continue;
1259				}
1260				/*
1261				 * The busy flags are only cleared at
1262				 * interrupt -- minimize the spl transitions
1263				 */
1264				if ((p->flags & PG_BUSY) || p->busy) {
1265					s = splvm();
1266					if ((p->flags & PG_BUSY) || p->busy) {
1267						p->flags |= PG_WANTED;
1268						tsleep(p, PVM, "vmopar", 0);
1269						splx(s);
1270						goto again;
1271					}
1272					splx(s);
1273				}
1274				if (clean_only) {
1275					vm_page_test_dirty(p);
1276					if (p->valid & p->dirty) {
1277						start += 1;
1278						size -= 1;
1279						continue;
1280					}
1281				}
1282				vm_page_protect(p, VM_PROT_NONE);
1283				PAGE_WAKEUP(p);
1284				vm_page_free(p);
1285			}
1286			start += 1;
1287			size -= 1;
1288		}
1289	}
1290	vm_object_pip_wakeup(object);
1291}
1292
1293/*
1294 *	Routine:	vm_object_coalesce
1295 *	Function:	Coalesces two objects backing up adjoining
1296 *			regions of memory into a single object.
1297 *
1298 *	returns TRUE if objects were combined.
1299 *
1300 *	NOTE:	Only works at the moment if the second object is NULL -
1301 *		if it's not, which object do we lock first?
1302 *
1303 *	Parameters:
1304 *		prev_object	First object to coalesce
1305 *		prev_offset	Offset into prev_object
1306 *		next_object	Second object into coalesce
1307 *		next_offset	Offset into next_object
1308 *
1309 *		prev_size	Size of reference to prev_object
1310 *		next_size	Size of reference to next_object
1311 *
1312 *	Conditions:
1313 *	The object must *not* be locked.
1314 */
1315boolean_t
1316vm_object_coalesce(prev_object, prev_pindex, prev_size, next_size)
1317	register vm_object_t prev_object;
1318	vm_pindex_t prev_pindex;
1319	vm_size_t prev_size, next_size;
1320{
1321	vm_size_t newsize;
1322
1323	if (prev_object == NULL) {
1324		return (TRUE);
1325	}
1326
1327	if (prev_object->type != OBJT_DEFAULT) {
1328		return (FALSE);
1329	}
1330
1331	/*
1332	 * Try to collapse the object first
1333	 */
1334	vm_object_collapse(prev_object);
1335
1336	/*
1337	 * Can't coalesce if: . more than one reference . paged out . shadows
1338	 * another object . has a copy elsewhere (any of which mean that the
1339	 * pages not mapped to prev_entry may be in use anyway)
1340	 */
1341
1342	if (prev_object->backing_object != NULL) {
1343		return (FALSE);
1344	}
1345
1346	prev_size >>= PAGE_SHIFT;
1347	next_size >>= PAGE_SHIFT;
1348
1349	if ((prev_object->ref_count > 1) &&
1350	    (prev_object->size != prev_pindex + prev_size)) {
1351		return (FALSE);
1352	}
1353
1354	/*
1355	 * Remove any pages that may still be in the object from a previous
1356	 * deallocation.
1357	 */
1358
1359	vm_object_page_remove(prev_object,
1360	    prev_pindex + prev_size,
1361	    prev_pindex + prev_size + next_size, FALSE);
1362
1363	/*
1364	 * Extend the object if necessary.
1365	 */
1366	newsize = prev_pindex + prev_size + next_size;
1367	if (newsize > prev_object->size)
1368		prev_object->size = newsize;
1369
1370	return (TRUE);
1371}
1372
1373#include "opt_ddb.h"
1374#ifdef DDB
1375#include <sys/kernel.h>
1376
1377#include <machine/cons.h>
1378
1379#include <ddb/ddb.h>
1380
1381static int	_vm_object_in_map __P((vm_map_t map, vm_object_t object,
1382				       vm_map_entry_t entry));
1383static int	vm_object_in_map __P((vm_object_t object));
1384
1385static int
1386_vm_object_in_map(map, object, entry)
1387	vm_map_t map;
1388	vm_object_t object;
1389	vm_map_entry_t entry;
1390{
1391	vm_map_t tmpm;
1392	vm_map_entry_t tmpe;
1393	vm_object_t obj;
1394	int entcount;
1395
1396	if (map == 0)
1397		return 0;
1398
1399	if (entry == 0) {
1400		tmpe = map->header.next;
1401		entcount = map->nentries;
1402		while (entcount-- && (tmpe != &map->header)) {
1403			if( _vm_object_in_map(map, object, tmpe)) {
1404				return 1;
1405			}
1406			tmpe = tmpe->next;
1407		}
1408	} else if (entry->eflags & (MAP_ENTRY_IS_A_MAP|MAP_ENTRY_IS_SUB_MAP)) {
1409		tmpm = entry->object.share_map;
1410		tmpe = tmpm->header.next;
1411		entcount = tmpm->nentries;
1412		while (entcount-- && tmpe != &tmpm->header) {
1413			if( _vm_object_in_map(tmpm, object, tmpe)) {
1414				return 1;
1415			}
1416			tmpe = tmpe->next;
1417		}
1418	} else if (obj = entry->object.vm_object) {
1419		for(; obj; obj=obj->backing_object)
1420			if( obj == object) {
1421				return 1;
1422			}
1423	}
1424	return 0;
1425}
1426
1427static int
1428vm_object_in_map( object)
1429	vm_object_t object;
1430{
1431	struct proc *p;
1432	for (p = allproc.lh_first; p != 0; p = p->p_list.le_next) {
1433		if( !p->p_vmspace /* || (p->p_flag & (P_SYSTEM|P_WEXIT)) */)
1434			continue;
1435		if( _vm_object_in_map(&p->p_vmspace->vm_map, object, 0))
1436			return 1;
1437	}
1438	if( _vm_object_in_map( kernel_map, object, 0))
1439		return 1;
1440	if( _vm_object_in_map( kmem_map, object, 0))
1441		return 1;
1442	if( _vm_object_in_map( pager_map, object, 0))
1443		return 1;
1444	if( _vm_object_in_map( buffer_map, object, 0))
1445		return 1;
1446	if( _vm_object_in_map( io_map, object, 0))
1447		return 1;
1448	if( _vm_object_in_map( phys_map, object, 0))
1449		return 1;
1450	if( _vm_object_in_map( mb_map, object, 0))
1451		return 1;
1452	if( _vm_object_in_map( u_map, object, 0))
1453		return 1;
1454	return 0;
1455}
1456
1457DB_SHOW_COMMAND(vmochk, vm_object_check)
1458{
1459	vm_object_t object;
1460
1461	/*
1462	 * make sure that internal objs are in a map somewhere
1463	 * and none have zero ref counts.
1464	 */
1465	for (object = TAILQ_FIRST(&vm_object_list);
1466			object != NULL;
1467			object = TAILQ_NEXT(object, object_list)) {
1468		if (object->handle == NULL &&
1469		    (object->type == OBJT_DEFAULT || object->type == OBJT_SWAP)) {
1470			if (object->ref_count == 0) {
1471				db_printf("vmochk: internal obj has zero ref count: %d\n",
1472					object->size);
1473			}
1474			if (!vm_object_in_map(object)) {
1475				db_printf("vmochk: internal obj is not in a map: "
1476		"ref: %d, size: %d: 0x%x, backing_object: 0x%x\n",
1477				    object->ref_count, object->size,
1478				    object->size, object->backing_object);
1479			}
1480		}
1481	}
1482}
1483
1484/*
1485 *	vm_object_print:	[ debug ]
1486 */
1487DB_SHOW_COMMAND(object, vm_object_print_static)
1488{
1489	/* XXX convert args. */
1490	vm_object_t object = (vm_object_t)addr;
1491	boolean_t full = have_addr;
1492
1493	register vm_page_t p;
1494
1495	/* XXX count is an (unused) arg.  Avoid shadowing it. */
1496#define	count	was_count
1497
1498	register int count;
1499
1500	if (object == NULL)
1501		return;
1502
1503	db_iprintf("Object 0x%x: size=0x%x, res=%d, ref=%d, ",
1504	    (int) object, (int) object->size,
1505	    object->resident_page_count, object->ref_count);
1506	db_printf("offset=0x%x, backing_object=(0x%x)+0x%x\n",
1507	    (int) object->paging_offset,
1508	    (int) object->backing_object, (int) object->backing_object_offset);
1509	db_printf("cache: next=%p, prev=%p\n",
1510	    TAILQ_NEXT(object, cached_list), TAILQ_PREV(object, cached_list));
1511
1512	if (!full)
1513		return;
1514
1515	db_indent += 2;
1516	count = 0;
1517	for (p = TAILQ_FIRST(&object->memq); p != NULL; p = TAILQ_NEXT(p, listq)) {
1518		if (count == 0)
1519			db_iprintf("memory:=");
1520		else if (count == 6) {
1521			db_printf("\n");
1522			db_iprintf(" ...");
1523			count = 0;
1524		} else
1525			db_printf(",");
1526		count++;
1527
1528		db_printf("(off=0x%lx,page=0x%lx)",
1529		    (u_long) p->pindex, (u_long) VM_PAGE_TO_PHYS(p));
1530	}
1531	if (count != 0)
1532		db_printf("\n");
1533	db_indent -= 2;
1534}
1535
1536/* XXX. */
1537#undef count
1538
1539/* XXX need this non-static entry for calling from vm_map_print. */
1540void
1541vm_object_print(addr, have_addr, count, modif)
1542	db_expr_t addr;
1543	boolean_t have_addr;
1544	db_expr_t count;
1545	char *modif;
1546{
1547	vm_object_print_static(addr, have_addr, count, modif);
1548}
1549
1550DB_SHOW_COMMAND(vmopag, vm_object_print_pages)
1551{
1552	vm_object_t object;
1553	int nl = 0;
1554	int c;
1555	for (object = TAILQ_FIRST(&vm_object_list);
1556			object != NULL;
1557			object = TAILQ_NEXT(object, object_list)) {
1558		vm_pindex_t idx, fidx;
1559		vm_pindex_t osize;
1560		vm_offset_t pa = -1, padiff;
1561		int rcount;
1562		vm_page_t m;
1563
1564		db_printf("new object: 0x%x\n", object);
1565		if ( nl > 18) {
1566			c = cngetc();
1567			if (c != ' ')
1568				return;
1569			nl = 0;
1570		}
1571		nl++;
1572		rcount = 0;
1573		fidx = 0;
1574		osize = object->size;
1575		if (osize > 128)
1576			osize = 128;
1577		for(idx=0;idx<osize;idx++) {
1578			m = vm_page_lookup(object, idx);
1579			if (m == NULL) {
1580				if (rcount) {
1581					db_printf(" index(%d)run(%d)pa(0x%x)\n",
1582						fidx, rcount, pa);
1583					if ( nl > 18) {
1584						c = cngetc();
1585						if (c != ' ')
1586							return;
1587						nl = 0;
1588					}
1589					nl++;
1590					rcount = 0;
1591				}
1592				continue;
1593			}
1594
1595
1596			if (rcount &&
1597				(VM_PAGE_TO_PHYS(m) == pa + rcount * PAGE_SIZE)) {
1598				++rcount;
1599				continue;
1600			}
1601			if (rcount) {
1602				padiff = pa + rcount * PAGE_SIZE - VM_PAGE_TO_PHYS(m);
1603				padiff >>= PAGE_SHIFT;
1604				padiff &= PQ_L2_MASK;
1605				if (padiff == 0) {
1606					pa = VM_PAGE_TO_PHYS(m) - rcount * PAGE_SIZE;
1607					++rcount;
1608					continue;
1609				}
1610				db_printf(" index(%d)run(%d)pa(0x%x)", fidx, rcount, pa);
1611				db_printf("pd(%d)\n", padiff);
1612				if ( nl > 18) {
1613					c = cngetc();
1614					if (c != ' ')
1615						return;
1616					nl = 0;
1617				}
1618				nl++;
1619			}
1620			fidx = idx;
1621			pa = VM_PAGE_TO_PHYS(m);
1622			rcount = 1;
1623		}
1624		if (rcount) {
1625			db_printf(" index(%d)run(%d)pa(0x%x)\n", fidx, rcount, pa);
1626			if ( nl > 18) {
1627				c = cngetc();
1628				if (c != ' ')
1629					return;
1630				nl = 0;
1631			}
1632			nl++;
1633		}
1634	}
1635}
1636#endif /* DDB */
1637