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