Added #ifdef DEBUG around some more debug code to reduce the size of the
[unix-history] / sys / vm / vm_object.c
CommitLineData
15637ed4
RG
1/*
2 * Copyright (c) 1991 Regents of the University of California.
3 * All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * The Mach Operating System project at Carnegie-Mellon University.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by the University of
19 * California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 *
36 * @(#)vm_object.c 7.4 (Berkeley) 5/7/91
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 * PATCHES MAGIC LEVEL PATCH THAT GOT US HERE
65 * -------------------- ----- ----------------------
66 * CURRENT PATCH LEVEL: 1 00147
67 * -------------------- ----- ----------------------
68 *
69 * 20 Apr 93 Paul Kranenburg Detect and prevent kernel deadlocks in
70 * VM system
71 */
72
73/*
74 * Virtual memory object module.
75 */
76
77#include "param.h"
78#include "malloc.h"
79
80#include "vm.h"
81#include "vm_page.h"
82
83/*
84 * Virtual memory objects maintain the actual data
85 * associated with allocated virtual memory. A given
86 * page of memory exists within exactly one object.
87 *
88 * An object is only deallocated when all "references"
89 * are given up. Only one "reference" to a given
90 * region of an object should be writeable.
91 *
92 * Associated with each object is a list of all resident
93 * memory pages belonging to that object; this list is
94 * maintained by the "vm_page" module, and locked by the object's
95 * lock.
96 *
97 * Each object also records a "pager" routine which is
98 * used to retrieve (and store) pages to the proper backing
99 * storage. In addition, objects may be backed by other
100 * objects from which they were virtual-copied.
101 *
102 * The only items within the object structure which are
103 * modified after time of creation are:
104 * reference count locked by object's lock
105 * pager routine locked by object's lock
106 *
107 */
108
109struct vm_object kernel_object_store;
110struct vm_object kmem_object_store;
111
112#define VM_OBJECT_HASH_COUNT 157
113
114int vm_cache_max = 100; /* can patch if necessary */
115queue_head_t vm_object_hashtable[VM_OBJECT_HASH_COUNT];
116
117long object_collapses = 0;
118long object_bypasses = 0;
119
120/*
121 * vm_object_init:
122 *
123 * Initialize the VM objects module.
124 */
125void vm_object_init()
126{
127 register int i;
128
129 queue_init(&vm_object_cached_list);
130 queue_init(&vm_object_list);
131 vm_object_count = 0;
132 simple_lock_init(&vm_cache_lock);
133 simple_lock_init(&vm_object_list_lock);
134
135 for (i = 0; i < VM_OBJECT_HASH_COUNT; i++)
136 queue_init(&vm_object_hashtable[i]);
137
138 kernel_object = &kernel_object_store;
139 _vm_object_allocate(VM_MAX_KERNEL_ADDRESS - VM_MIN_KERNEL_ADDRESS,
140 kernel_object);
141
142 kmem_object = &kmem_object_store;
143 _vm_object_allocate(VM_KMEM_SIZE + VM_MBUF_SIZE, kmem_object);
144}
145
146/*
147 * vm_object_allocate:
148 *
149 * Returns a new object with the given size.
150 */
151
152vm_object_t vm_object_allocate(size)
153 vm_size_t size;
154{
155 register vm_object_t result;
156
157 result = (vm_object_t)
158 malloc((u_long)sizeof *result, M_VMOBJ, M_WAITOK);
159
160 _vm_object_allocate(size, result);
161
162 return(result);
163}
164
165_vm_object_allocate(size, object)
166 vm_size_t size;
167 register vm_object_t object;
168{
169 queue_init(&object->memq);
170 vm_object_lock_init(object);
171 object->ref_count = 1;
172 object->resident_page_count = 0;
173 object->size = size;
174 object->can_persist = FALSE;
175 object->paging_in_progress = 0;
176 object->copy = NULL;
177
178 /*
179 * Object starts out read-write, with no pager.
180 */
181
182 object->pager = NULL;
183 object->pager_ready = FALSE;
184 object->internal = TRUE; /* vm_allocate_with_pager will reset */
185 object->paging_offset = 0;
186 object->shadow = NULL;
187 object->shadow_offset = (vm_offset_t) 0;
188
189 simple_lock(&vm_object_list_lock);
190 queue_enter(&vm_object_list, object, vm_object_t, object_list);
191 vm_object_count++;
192 simple_unlock(&vm_object_list_lock);
193}
194
195/*
196 * vm_object_reference:
197 *
198 * Gets another reference to the given object.
199 */
200void vm_object_reference(object)
201 register vm_object_t object;
202{
203 if (object == NULL)
204 return;
205
206 vm_object_lock(object);
207 object->ref_count++;
208 vm_object_unlock(object);
209}
210
211/*
212 * vm_object_deallocate:
213 *
214 * Release a reference to the specified object,
215 * gained either through a vm_object_allocate
216 * or a vm_object_reference call. When all references
217 * are gone, storage associated with this object
218 * may be relinquished.
219 *
220 * No object may be locked.
221 */
222void vm_object_deallocate(object)
223 register vm_object_t object;
224{
225 vm_object_t temp;
226
227 while (object != NULL) {
228
229 /*
230 * The cache holds a reference (uncounted) to
231 * the object; we must lock it before removing
232 * the object.
233 */
234
235 vm_object_cache_lock();
236
237 /*
238 * Lose the reference
239 */
240 vm_object_lock(object);
241 if (--(object->ref_count) != 0) {
242
243 /*
244 * If there are still references, then
245 * we are done.
246 */
247 vm_object_unlock(object);
248 vm_object_cache_unlock();
249 return;
250 }
251
252 /*
253 * See if this object can persist. If so, enter
254 * it in the cache, then deactivate all of its
255 * pages.
256 */
257
258 if (object->can_persist) {
259 register vm_page_t p;
260
261 /*
262 * Check for dirty pages in object
263 * Print warning as this may signify kernel bugs
264 * pk@cs.few.eur.nl - 4/15/93
265 */
266 p = (vm_page_t) queue_first(&object->memq);
267 while (!queue_end(&object->memq, (queue_entry_t) p)) {
268 VM_PAGE_CHECK(p);
269
270 if (pmap_is_modified(VM_PAGE_TO_PHYS(p)) ||
271 !p->clean) {
272
273 printf("vm_object_dealloc: persistent object %x isn't clean\n", object);
274 goto cant_persist;
275 }
276
277 p = (vm_page_t) queue_next(&p->listq);
278 }
279
280 queue_enter(&vm_object_cached_list, object,
281 vm_object_t, cached_list);
282 vm_object_cached++;
283 vm_object_cache_unlock();
284
285 vm_object_deactivate_pages(object);
286 vm_object_unlock(object);
287
288 vm_object_cache_trim();
289 return;
290 }
291 cant_persist:;
292
293 /*
294 * Make sure no one can look us up now.
295 */
296 vm_object_remove(object->pager);
297 vm_object_cache_unlock();
298
299 temp = object->shadow;
300 vm_object_terminate(object);
301 /* unlocks and deallocates object */
302 object = temp;
303 }
304}
305
306
307/*
308 * vm_object_terminate actually destroys the specified object, freeing
309 * up all previously used resources.
310 *
311 * The object must be locked.
312 */
313void vm_object_terminate(object)
314 register vm_object_t object;
315{
316 register vm_page_t p;
317 vm_object_t shadow_object;
318
319 /*
320 * Detach the object from its shadow if we are the shadow's
321 * copy.
322 */
323 if ((shadow_object = object->shadow) != NULL) {
324 vm_object_lock(shadow_object);
325 if (shadow_object->copy == object)
326 shadow_object->copy = NULL;
327#if 0
328 else if (shadow_object->copy != NULL)
329 panic("vm_object_terminate: copy/shadow inconsistency");
330#endif
331 vm_object_unlock(shadow_object);
332 }
333
334 /*
335 * Wait until the pageout daemon is through
336 * with the object.
337 */
338
339 while (object->paging_in_progress != 0) {
340 vm_object_sleep(object, object, FALSE);
341 vm_object_lock(object);
342 }
343
344
345 /*
346 * While the paging system is locked,
347 * pull the object's pages off the active
348 * and inactive queues. This keeps the
349 * pageout daemon from playing with them
350 * during vm_pager_deallocate.
351 *
352 * We can't free the pages yet, because the
353 * object's pager may have to write them out
354 * before deallocating the paging space.
355 */
356
357 p = (vm_page_t) queue_first(&object->memq);
358 while (!queue_end(&object->memq, (queue_entry_t) p)) {
359 VM_PAGE_CHECK(p);
360
361 vm_page_lock_queues();
362 if (p->active) {
363 queue_remove(&vm_page_queue_active, p, vm_page_t,
364 pageq);
365 p->active = FALSE;
366 vm_page_active_count--;
367 }
368
369 if (p->inactive) {
370 queue_remove(&vm_page_queue_inactive, p, vm_page_t,
371 pageq);
372 p->inactive = FALSE;
373 vm_page_inactive_count--;
374 }
375 vm_page_unlock_queues();
376 p = (vm_page_t) queue_next(&p->listq);
377 }
378
379 vm_object_unlock(object);
380
381 if (object->paging_in_progress != 0)
382 panic("vm_object_deallocate: pageout in progress");
383
384 /*
385 * Clean and free the pages, as appropriate.
386 * All references to the object are gone,
387 * so we don't need to lock it.
388 */
389
390 if (!object->internal) {
391 vm_object_lock(object);
392 vm_object_page_clean(object, 0, 0);
393 vm_object_unlock(object);
394 }
395 while (!queue_empty(&object->memq)) {
396 p = (vm_page_t) queue_first(&object->memq);
397
398 VM_PAGE_CHECK(p);
399
400 vm_page_lock_queues();
401 vm_page_free(p);
402 vm_page_unlock_queues();
403 }
404
405 /*
406 * Let the pager know object is dead.
407 */
408
409 if (object->pager != NULL)
410 vm_pager_deallocate(object->pager);
411
412
413 simple_lock(&vm_object_list_lock);
414 queue_remove(&vm_object_list, object, vm_object_t, object_list);
415 vm_object_count--;
416 simple_unlock(&vm_object_list_lock);
417
418 /*
419 * Free the space for the object.
420 */
421
422 free((caddr_t)object, M_VMOBJ);
423}
424
425/*
426 * vm_object_page_clean
427 *
428 * Clean all dirty pages in the specified range of object.
429 * Leaves page on whatever queue it is currently on.
430 *
431 * Odd semantics: if start == end, we clean everything.
432 *
433 * The object must be locked.
434 */
435vm_object_page_clean(object, start, end)
436 register vm_object_t object;
437 register vm_offset_t start;
438 register vm_offset_t end;
439{
440 register vm_page_t p;
441
442 if (object->pager == NULL)
443 return;
444
445again:
446 p = (vm_page_t) queue_first(&object->memq);
447 while (!queue_end(&object->memq, (queue_entry_t) p)) {
448 if (start == end ||
449 p->offset >= start && p->offset < end) {
450 if (p->clean && pmap_is_modified(VM_PAGE_TO_PHYS(p)))
451 p->clean = FALSE;
452 pmap_page_protect(VM_PAGE_TO_PHYS(p), VM_PROT_NONE);
453 if (!p->clean) {
454 p->busy = TRUE;
455 object->paging_in_progress++;
456 vm_object_unlock(object);
457 (void) vm_pager_put(object->pager, p, TRUE);
458 vm_object_lock(object);
459 object->paging_in_progress--;
460 p->busy = FALSE;
461 PAGE_WAKEUP(p);
462 goto again;
463 }
464 }
465 p = (vm_page_t) queue_next(&p->listq);
466 }
467}
468
469/*
470 * vm_object_deactivate_pages
471 *
472 * Deactivate all pages in the specified object. (Keep its pages
473 * in memory even though it is no longer referenced.)
474 *
475 * The object must be locked.
476 */
477vm_object_deactivate_pages(object)
478 register vm_object_t object;
479{
480 register vm_page_t p, next;
481
482 p = (vm_page_t) queue_first(&object->memq);
483 while (!queue_end(&object->memq, (queue_entry_t) p)) {
484 next = (vm_page_t) queue_next(&p->listq);
485 vm_page_lock_queues();
8820571b
NW
486 if (!p->busy)
487 vm_page_deactivate(p); /* optimisation from mach 3.0 -
488 * andrew@werple.apana.org.au,
489 * Feb '93
490 */
15637ed4
RG
491 vm_page_unlock_queues();
492 p = next;
493 }
494}
495
496/*
497 * Trim the object cache to size.
498 */
499vm_object_cache_trim()
500{
501 register vm_object_t object;
502
503 vm_object_cache_lock();
504 while (vm_object_cached > vm_cache_max) {
505 object = (vm_object_t) queue_first(&vm_object_cached_list);
506 vm_object_cache_unlock();
507
508 if (object != vm_object_lookup(object->pager))
509 panic("vm_object_deactivate: I'm sooo confused.");
510
511 pager_cache(object, FALSE);
512
513 vm_object_cache_lock();
514 }
515 vm_object_cache_unlock();
516}
517
518
519/*
520 * vm_object_shutdown()
521 *
522 * Shut down the object system. Unfortunately, while we
523 * may be trying to do this, init is happily waiting for
524 * processes to exit, and therefore will be causing some objects
525 * to be deallocated. To handle this, we gain a fake reference
526 * to all objects we release paging areas for. This will prevent
527 * a duplicate deallocation. This routine is probably full of
528 * race conditions!
529 */
530
531void vm_object_shutdown()
532{
533 register vm_object_t object;
534
535 /*
536 * Clean up the object cache *before* we screw up the reference
537 * counts on all of the objects.
538 */
539
540 vm_object_cache_clear();
541
542 printf("free paging spaces: ");
543
544 /*
545 * First we gain a reference to each object so that
546 * no one else will deallocate them.
547 */
548
549 simple_lock(&vm_object_list_lock);
550 object = (vm_object_t) queue_first(&vm_object_list);
551 while (!queue_end(&vm_object_list, (queue_entry_t) object)) {
552 vm_object_reference(object);
553 object = (vm_object_t) queue_next(&object->object_list);
554 }
555 simple_unlock(&vm_object_list_lock);
556
557 /*
558 * Now we deallocate all the paging areas. We don't need
559 * to lock anything because we've reduced to a single
560 * processor while shutting down. This also assumes that
561 * no new objects are being created.
562 */
563
564 object = (vm_object_t) queue_first(&vm_object_list);
565 while (!queue_end(&vm_object_list, (queue_entry_t) object)) {
566 if (object->pager != NULL)
567 vm_pager_deallocate(object->pager);
568 object = (vm_object_t) queue_next(&object->object_list);
569 printf(".");
570 }
571 printf("done.\n");
572}
573
574/*
575 * vm_object_pmap_copy:
576 *
577 * Makes all physical pages in the specified
578 * object range copy-on-write. No writeable
579 * references to these pages should remain.
580 *
581 * The object must *not* be locked.
582 */
583void vm_object_pmap_copy(object, start, end)
584 register vm_object_t object;
585 register vm_offset_t start;
586 register vm_offset_t end;
587{
588 register vm_page_t p;
589
590 if (object == NULL)
591 return;
592
593 vm_object_lock(object);
594 p = (vm_page_t) queue_first(&object->memq);
595 while (!queue_end(&object->memq, (queue_entry_t) p)) {
596 if ((start <= p->offset) && (p->offset < end)) {
597 pmap_page_protect(VM_PAGE_TO_PHYS(p), VM_PROT_READ);
598 p->copy_on_write = TRUE;
599 }
600 p = (vm_page_t) queue_next(&p->listq);
601 }
602 vm_object_unlock(object);
603}
604
605/*
606 * vm_object_pmap_remove:
607 *
608 * Removes all physical pages in the specified
609 * object range from all physical maps.
610 *
611 * The object must *not* be locked.
612 */
613void vm_object_pmap_remove(object, start, end)
614 register vm_object_t object;
615 register vm_offset_t start;
616 register vm_offset_t end;
617{
618 register vm_page_t p;
619
620 if (object == NULL)
621 return;
622
623 vm_object_lock(object);
624 p = (vm_page_t) queue_first(&object->memq);
625 while (!queue_end(&object->memq, (queue_entry_t) p)) {
626 if ((start <= p->offset) && (p->offset < end))
627 pmap_page_protect(VM_PAGE_TO_PHYS(p), VM_PROT_NONE);
628 p = (vm_page_t) queue_next(&p->listq);
629 }
630 vm_object_unlock(object);
631}
632
633/*
634 * vm_object_copy:
635 *
636 * Create a new object which is a copy of an existing
637 * object, and mark all of the pages in the existing
638 * object 'copy-on-write'. The new object has one reference.
639 * Returns the new object.
640 *
641 * May defer the copy until later if the object is not backed
642 * up by a non-default pager.
643 */
644void vm_object_copy(src_object, src_offset, size,
645 dst_object, dst_offset, src_needs_copy)
646 register vm_object_t src_object;
647 vm_offset_t src_offset;
648 vm_size_t size;
649 vm_object_t *dst_object; /* OUT */
650 vm_offset_t *dst_offset; /* OUT */
651 boolean_t *src_needs_copy; /* OUT */
652{
653 register vm_object_t new_copy;
654 register vm_object_t old_copy;
655 vm_offset_t new_start, new_end;
656
657 register vm_page_t p;
658
659 if (src_object == NULL) {
660 /*
661 * Nothing to copy
662 */
663 *dst_object = NULL;
664 *dst_offset = 0;
665 *src_needs_copy = FALSE;
666 return;
667 }
668
669 /*
670 * If the object's pager is null_pager or the
671 * default pager, we don't have to make a copy
672 * of it. Instead, we set the needs copy flag and
673 * make a shadow later.
674 */
675
676 vm_object_lock(src_object);
677 if (src_object->pager == NULL ||
678 src_object->internal) {
679
680 /*
681 * Make another reference to the object
682 */
683 src_object->ref_count++;
684
685 /*
686 * Mark all of the pages copy-on-write.
687 */
688 for (p = (vm_page_t) queue_first(&src_object->memq);
689 !queue_end(&src_object->memq, (queue_entry_t)p);
690 p = (vm_page_t) queue_next(&p->listq)) {
691 if (src_offset <= p->offset &&
692 p->offset < src_offset + size)
693 p->copy_on_write = TRUE;
694 }
695 vm_object_unlock(src_object);
696
697 *dst_object = src_object;
698 *dst_offset = src_offset;
699
700 /*
701 * Must make a shadow when write is desired
702 */
703 *src_needs_copy = TRUE;
704 return;
705 }
706
707 /*
708 * Try to collapse the object before copying it.
709 */
710 vm_object_collapse(src_object);
711
712 /*
713 * If the object has a pager, the pager wants to
714 * see all of the changes. We need a copy-object
715 * for the changed pages.
716 *
717 * If there is a copy-object, and it is empty,
718 * no changes have been made to the object since the
719 * copy-object was made. We can use the same copy-
720 * object.
721 */
722
723 Retry1:
724 old_copy = src_object->copy;
725 if (old_copy != NULL) {
726 /*
727 * Try to get the locks (out of order)
728 */
729 if (!vm_object_lock_try(old_copy)) {
730 vm_object_unlock(src_object);
731
732 /* should spin a bit here... */
733 vm_object_lock(src_object);
734 goto Retry1;
735 }
736
737 if (old_copy->resident_page_count == 0 &&
738 old_copy->pager == NULL) {
739 /*
740 * Return another reference to
741 * the existing copy-object.
742 */
743 old_copy->ref_count++;
744 vm_object_unlock(old_copy);
745 vm_object_unlock(src_object);
746 *dst_object = old_copy;
747 *dst_offset = src_offset;
748 *src_needs_copy = FALSE;
749 return;
750 }
751 vm_object_unlock(old_copy);
752 }
753 vm_object_unlock(src_object);
754
755 /*
756 * If the object has a pager, the pager wants
757 * to see all of the changes. We must make
758 * a copy-object and put the changed pages there.
759 *
760 * The copy-object is always made large enough to
761 * completely shadow the original object, since
762 * it may have several users who want to shadow
763 * the original object at different points.
764 */
765
766 new_copy = vm_object_allocate(src_object->size);
767
768 Retry2:
769 vm_object_lock(src_object);
770 /*
771 * Copy object may have changed while we were unlocked
772 */
773 old_copy = src_object->copy;
774 if (old_copy != NULL) {
775 /*
776 * Try to get the locks (out of order)
777 */
778 if (!vm_object_lock_try(old_copy)) {
779 vm_object_unlock(src_object);
780 goto Retry2;
781 }
782
783 /*
784 * Consistency check
785 */
786 if (old_copy->shadow != src_object ||
787 old_copy->shadow_offset != (vm_offset_t) 0)
788 panic("vm_object_copy: copy/shadow inconsistency");
789
790 /*
791 * Make the old copy-object shadow the new one.
792 * It will receive no more pages from the original
793 * object.
794 */
795
796 src_object->ref_count--; /* remove ref. from old_copy */
797 old_copy->shadow = new_copy;
798 new_copy->ref_count++; /* locking not needed - we
799 have the only pointer */
800 vm_object_unlock(old_copy); /* done with old_copy */
801 }
802
803 new_start = (vm_offset_t) 0; /* always shadow original at 0 */
804 new_end = (vm_offset_t) new_copy->size; /* for the whole object */
805
806 /*
807 * Point the new copy at the existing object.
808 */
809
810 new_copy->shadow = src_object;
811 new_copy->shadow_offset = new_start;
812 src_object->ref_count++;
813 src_object->copy = new_copy;
814
815 /*
816 * Mark all the affected pages of the existing object
817 * copy-on-write.
818 */
819 p = (vm_page_t) queue_first(&src_object->memq);
820 while (!queue_end(&src_object->memq, (queue_entry_t) p)) {
821 if ((new_start <= p->offset) && (p->offset < new_end))
822 p->copy_on_write = TRUE;
823 p = (vm_page_t) queue_next(&p->listq);
824 }
825
826 vm_object_unlock(src_object);
827
828 *dst_object = new_copy;
829 *dst_offset = src_offset - new_start;
830 *src_needs_copy = FALSE;
831}
832
833/*
834 * vm_object_shadow:
835 *
836 * Create a new object which is backed by the
837 * specified existing object range. The source
838 * object reference is deallocated.
839 *
840 * The new object and offset into that object
841 * are returned in the source parameters.
842 */
843
844void vm_object_shadow(object, offset, length)
845 vm_object_t *object; /* IN/OUT */
846 vm_offset_t *offset; /* IN/OUT */
847 vm_size_t length;
848{
849 register vm_object_t source;
850 register vm_object_t result;
851
852 source = *object;
853
854 /*
855 * Allocate a new object with the given length
856 */
857
858 if ((result = vm_object_allocate(length)) == NULL)
859 panic("vm_object_shadow: no object for shadowing");
860
861 /*
862 * The new object shadows the source object, adding
863 * a reference to it. Our caller changes his reference
864 * to point to the new object, removing a reference to
865 * the source object. Net result: no change of reference
866 * count.
867 */
868 result->shadow = source;
869
870 /*
871 * Store the offset into the source object,
872 * and fix up the offset into the new object.
873 */
874
875 result->shadow_offset = *offset;
876
877 /*
878 * Return the new things
879 */
880
881 *offset = 0;
882 *object = result;
883}
884
885/*
886 * Set the specified object's pager to the specified pager.
887 */
888
889void vm_object_setpager(object, pager, paging_offset,
890 read_only)
891 vm_object_t object;
892 vm_pager_t pager;
893 vm_offset_t paging_offset;
894 boolean_t read_only;
895{
896#ifdef lint
897 read_only++; /* No longer used */
898#endif lint
899
900 vm_object_lock(object); /* XXX ? */
901 object->pager = pager;
902 object->paging_offset = paging_offset;
903 vm_object_unlock(object); /* XXX ? */
904}
905
906/*
907 * vm_object_hash hashes the pager/id pair.
908 */
909
910#define vm_object_hash(pager) \
911 (((unsigned)pager)%VM_OBJECT_HASH_COUNT)
912
913/*
914 * vm_object_lookup looks in the object cache for an object with the
915 * specified pager and paging id.
916 */
917
918vm_object_t vm_object_lookup(pager)
919 vm_pager_t pager;
920{
921 register queue_t bucket;
922 register vm_object_hash_entry_t entry;
923 vm_object_t object;
924
925 bucket = &vm_object_hashtable[vm_object_hash(pager)];
926
927 vm_object_cache_lock();
928
929 entry = (vm_object_hash_entry_t) queue_first(bucket);
930 while (!queue_end(bucket, (queue_entry_t) entry)) {
931 object = entry->object;
932 if (object->pager == pager) {
933 vm_object_lock(object);
934 if (object->ref_count == 0) {
935 queue_remove(&vm_object_cached_list, object,
936 vm_object_t, cached_list);
937 vm_object_cached--;
938 }
939 object->ref_count++;
940 vm_object_unlock(object);
941 vm_object_cache_unlock();
942 return(object);
943 }
944 entry = (vm_object_hash_entry_t) queue_next(&entry->hash_links);
945 }
946
947 vm_object_cache_unlock();
948 return(NULL);
949}
950
951/*
952 * vm_object_enter enters the specified object/pager/id into
953 * the hash table.
954 */
955
956void vm_object_enter(object, pager)
957 vm_object_t object;
958 vm_pager_t pager;
959{
960 register queue_t bucket;
961 register vm_object_hash_entry_t entry;
962
963 /*
964 * We don't cache null objects, and we can't cache
965 * objects with the null pager.
966 */
967
968 if (object == NULL)
969 return;
970 if (pager == NULL)
971 return;
972
973 bucket = &vm_object_hashtable[vm_object_hash(pager)];
974 entry = (vm_object_hash_entry_t)
975 malloc((u_long)sizeof *entry, M_VMOBJHASH, M_WAITOK);
976 entry->object = object;
977 object->can_persist = TRUE;
978
979 vm_object_cache_lock();
980 queue_enter(bucket, entry, vm_object_hash_entry_t, hash_links);
981 vm_object_cache_unlock();
982}
983
984/*
985 * vm_object_remove:
986 *
987 * Remove the pager from the hash table.
988 * Note: This assumes that the object cache
989 * is locked. XXX this should be fixed
990 * by reorganizing vm_object_deallocate.
991 */
992vm_object_remove(pager)
993 register vm_pager_t pager;
994{
995 register queue_t bucket;
996 register vm_object_hash_entry_t entry;
997 register vm_object_t object;
998
999 bucket = &vm_object_hashtable[vm_object_hash(pager)];
1000
1001 entry = (vm_object_hash_entry_t) queue_first(bucket);
1002 while (!queue_end(bucket, (queue_entry_t) entry)) {
1003 object = entry->object;
1004 if (object->pager == pager) {
1005 queue_remove(bucket, entry, vm_object_hash_entry_t,
1006 hash_links);
1007 free((caddr_t)entry, M_VMOBJHASH);
1008 break;
1009 }
1010 entry = (vm_object_hash_entry_t) queue_next(&entry->hash_links);
1011 }
1012}
1013
1014/*
1015 * vm_object_cache_clear removes all objects from the cache.
1016 *
1017 */
1018
1019void vm_object_cache_clear()
1020{
1021 register vm_object_t object;
1022
1023 /*
1024 * Remove each object in the cache by scanning down the
1025 * list of cached objects.
1026 */
1027 vm_object_cache_lock();
1028 while (!queue_empty(&vm_object_cached_list)) {
1029 object = (vm_object_t) queue_first(&vm_object_cached_list);
1030 vm_object_cache_unlock();
1031
1032 /*
1033 * Note: it is important that we use vm_object_lookup
1034 * to gain a reference, and not vm_object_reference, because
1035 * the logic for removing an object from the cache lies in
1036 * lookup.
1037 */
1038 if (object != vm_object_lookup(object->pager))
1039 panic("vm_object_cache_clear: I'm sooo confused.");
1040 pager_cache(object, FALSE);
1041
1042 vm_object_cache_lock();
1043 }
1044 vm_object_cache_unlock();
1045}
1046
1047boolean_t vm_object_collapse_allowed = TRUE;
1048/*
1049 * vm_object_collapse:
1050 *
1051 * Collapse an object with the object backing it.
1052 * Pages in the backing object are moved into the
1053 * parent, and the backing object is deallocated.
1054 *
1055 * Requires that the object be locked and the page
1056 * queues be unlocked.
1057 *
1058 */
1059void vm_object_collapse(object)
1060 register vm_object_t object;
1061
1062{
1063 register vm_object_t backing_object;
1064 register vm_offset_t backing_offset;
1065 register vm_size_t size;
1066 register vm_offset_t new_offset;
1067 register vm_page_t p, pp;
1068
1069 if (!vm_object_collapse_allowed)
1070 return;
1071
1072 while (TRUE) {
1073 /*
1074 * Verify that the conditions are right for collapse:
1075 *
1076 * The object exists and no pages in it are currently
1077 * being paged out (or have ever been paged out).
1078 */
1079 if (object == NULL ||
1080 object->paging_in_progress != 0 ||
1081 object->pager != NULL)
1082 return;
1083
1084 /*
1085 * There is a backing object, and
1086 */
1087
1088 if ((backing_object = object->shadow) == NULL)
1089 return;
1090
1091 vm_object_lock(backing_object);
1092 /*
1093 * ...
1094 * The backing object is not read_only,
1095 * and no pages in the backing object are
1096 * currently being paged out.
1097 * The backing object is internal.
1098 */
1099
1100 if (!backing_object->internal ||
1101 backing_object->paging_in_progress != 0) {
1102 vm_object_unlock(backing_object);
1103 return;
1104 }
1105
1106 /*
1107 * The backing object can't be a copy-object:
1108 * the shadow_offset for the copy-object must stay
1109 * as 0. Furthermore (for the 'we have all the
1110 * pages' case), if we bypass backing_object and
1111 * just shadow the next object in the chain, old
1112 * pages from that object would then have to be copied
1113 * BOTH into the (former) backing_object and into the
1114 * parent object.
1115 */
1116 if (backing_object->shadow != NULL &&
1117 backing_object->shadow->copy != NULL) {
1118 vm_object_unlock(backing_object);
1119 return;
1120 }
1121
1122 /*
1123 * We know that we can either collapse the backing
1124 * object (if the parent is the only reference to
1125 * it) or (perhaps) remove the parent's reference
1126 * to it.
1127 */
1128
1129 backing_offset = object->shadow_offset;
1130 size = object->size;
1131
1132 /*
1133 * If there is exactly one reference to the backing
1134 * object, we can collapse it into the parent.
1135 */
1136
1137 if (backing_object->ref_count == 1) {
1138
1139 /*
1140 * We can collapse the backing object.
1141 *
1142 * Move all in-memory pages from backing_object
1143 * to the parent. Pages that have been paged out
1144 * will be overwritten by any of the parent's
1145 * pages that shadow them.
1146 */
1147
1148 while (!queue_empty(&backing_object->memq)) {
1149
1150 p = (vm_page_t)
1151 queue_first(&backing_object->memq);
1152
1153 new_offset = (p->offset - backing_offset);
1154
1155 /*
1156 * If the parent has a page here, or if
1157 * this page falls outside the parent,
1158 * dispose of it.
1159 *
1160 * Otherwise, move it as planned.
1161 */
1162
1163 if (p->offset < backing_offset ||
1164 new_offset >= size) {
1165 vm_page_lock_queues();
1166 vm_page_free(p);
1167 vm_page_unlock_queues();
1168 } else {
1169 pp = vm_page_lookup(object, new_offset);
1170 if (pp != NULL && !pp->fake) {
1171 vm_page_lock_queues();
1172 vm_page_free(p);
1173 vm_page_unlock_queues();
1174 }
1175 else {
1176 if (pp) {
8820571b
NW
1177#if 1
1178 /*
1179 * This should never happen -- the
1180 * parent cannot have ever had an
1181 * external memory object, and thus
1182 * cannot have absent pages.
1183 */
1184 panic("vm_object_collapse: bad case");
1185 /* andrew@werple.apana.org.au - from
1186 mach 3.0 VM */
1187#else
15637ed4
RG
1188 /* may be someone waiting for it */
1189 PAGE_WAKEUP(pp);
1190 vm_page_lock_queues();
1191 vm_page_free(pp);
1192 vm_page_unlock_queues();
8820571b 1193#endif
15637ed4 1194 }
8820571b
NW
1195 /*
1196 * Parent now has no page.
1197 * Move the backing object's page
1198 * up.
1199 */
15637ed4
RG
1200 vm_page_rename(p, object, new_offset);
1201 }
1202 }
1203 }
1204
1205 /*
1206 * Move the pager from backing_object to object.
1207 *
1208 * XXX We're only using part of the paging space
1209 * for keeps now... we ought to discard the
1210 * unused portion.
1211 */
1212
1213 object->pager = backing_object->pager;
8820571b
NW
1214#if 1
1215 /* Mach 3.0 code */
1216 /* andrew@werple.apana.org.au, 12 Feb 1993 */
1217
1218 /*
1219 * If there is no pager, leave paging-offset alone.
1220 */
1221 if (object->pager)
1222 object->paging_offset =
1223 backing_object->paging_offset +
1224 backing_offset;
1225#else
1226 /* old VM 2.5 version */
15637ed4 1227 object->paging_offset += backing_offset;
8820571b 1228#endif
15637ed4
RG
1229
1230 backing_object->pager = NULL;
1231
1232 /*
1233 * Object now shadows whatever backing_object did.
1234 * Note that the reference to backing_object->shadow
1235 * moves from within backing_object to within object.
1236 */
1237
1238 object->shadow = backing_object->shadow;
1239 object->shadow_offset += backing_object->shadow_offset;
1240 if (object->shadow != NULL &&
1241 object->shadow->copy != NULL) {
1242 panic("vm_object_collapse: we collapsed a copy-object!");
1243 }
1244 /*
1245 * Discard backing_object.
1246 *
1247 * Since the backing object has no pages, no
1248 * pager left, and no object references within it,
1249 * all that is necessary is to dispose of it.
1250 */
1251
1252 vm_object_unlock(backing_object);
1253
1254 simple_lock(&vm_object_list_lock);
1255 queue_remove(&vm_object_list, backing_object,
1256 vm_object_t, object_list);
1257 vm_object_count--;
1258 simple_unlock(&vm_object_list_lock);
1259
1260 free((caddr_t)backing_object, M_VMOBJ);
1261
1262 object_collapses++;
1263 }
1264 else {
1265 /*
1266 * If all of the pages in the backing object are
1267 * shadowed by the parent object, the parent
1268 * object no longer has to shadow the backing
1269 * object; it can shadow the next one in the
1270 * chain.
1271 *
1272 * The backing object must not be paged out - we'd
1273 * have to check all of the paged-out pages, as
1274 * well.
1275 */
1276
1277 if (backing_object->pager != NULL) {
1278 vm_object_unlock(backing_object);
1279 return;
1280 }
1281
1282 /*
1283 * Should have a check for a 'small' number
1284 * of pages here.
1285 */
1286
1287 p = (vm_page_t) queue_first(&backing_object->memq);
1288 while (!queue_end(&backing_object->memq,
1289 (queue_entry_t) p)) {
1290
1291 new_offset = (p->offset - backing_offset);
1292
1293 /*
1294 * If the parent has a page here, or if
1295 * this page falls outside the parent,
1296 * keep going.
1297 *
1298 * Otherwise, the backing_object must be
1299 * left in the chain.
1300 */
1301
1302 if (p->offset >= backing_offset &&
1303 new_offset <= size &&
1304 ((pp = vm_page_lookup(object, new_offset))
1305 == NULL ||
1306 pp->fake)) {
1307 /*
1308 * Page still needed.
1309 * Can't go any further.
1310 */
1311 vm_object_unlock(backing_object);
1312 return;
1313 }
1314 p = (vm_page_t) queue_next(&p->listq);
1315 }
1316
1317 /*
1318 * Make the parent shadow the next object
1319 * in the chain. Deallocating backing_object
1320 * will not remove it, since its reference
1321 * count is at least 2.
1322 */
1323
1324 vm_object_reference(object->shadow = backing_object->shadow);
1325 object->shadow_offset += backing_object->shadow_offset;
1326
8820571b
NW
1327#if 1
1328 /* Mach 3.0 code */
1329 /* andrew@werple.apana.org.au, 12 Feb 1993 */
1330
1331 /*
1332 * Backing object might have had a copy pointer
1333 * to us. If it did, clear it.
1334 */
1335 if (backing_object->copy == object)
1336 backing_object->copy = NULL;
1337#endif
1338
15637ed4
RG
1339 /* Drop the reference count on backing_object.
1340 * Since its ref_count was at least 2, it
1341 * will not vanish; so we don't need to call
1342 * vm_object_deallocate.
1343 */
1344 backing_object->ref_count--;
1345 vm_object_unlock(backing_object);
1346
1347 object_bypasses ++;
1348
1349 }
1350
1351 /*
1352 * Try again with this object's new backing object.
1353 */
1354 }
1355}
1356
1357/*
1358 * vm_object_page_remove: [internal]
1359 *
1360 * Removes all physical pages in the specified
1361 * object range from the object's list of pages.
1362 *
1363 * The object must be locked.
1364 */
1365void vm_object_page_remove(object, start, end)
1366 register vm_object_t object;
1367 register vm_offset_t start;
1368 register vm_offset_t end;
1369{
1370 register vm_page_t p, next;
1371
1372 if (object == NULL)
1373 return;
1374
1375 p = (vm_page_t) queue_first(&object->memq);
1376 while (!queue_end(&object->memq, (queue_entry_t) p)) {
1377 next = (vm_page_t) queue_next(&p->listq);
1378 if ((start <= p->offset) && (p->offset < end)) {
1379 pmap_page_protect(VM_PAGE_TO_PHYS(p), VM_PROT_NONE);
1380 vm_page_lock_queues();
1381 vm_page_free(p);
1382 vm_page_unlock_queues();
1383 }
1384 p = next;
1385 }
1386}
1387
1388/*
1389 * Routine: vm_object_coalesce
1390 * Function: Coalesces two objects backing up adjoining
1391 * regions of memory into a single object.
1392 *
1393 * returns TRUE if objects were combined.
1394 *
1395 * NOTE: Only works at the moment if the second object is NULL -
1396 * if it's not, which object do we lock first?
1397 *
1398 * Parameters:
1399 * prev_object First object to coalesce
1400 * prev_offset Offset into prev_object
1401 * next_object Second object into coalesce
1402 * next_offset Offset into next_object
1403 *
1404 * prev_size Size of reference to prev_object
1405 * next_size Size of reference to next_object
1406 *
1407 * Conditions:
1408 * The object must *not* be locked.
1409 */
1410boolean_t vm_object_coalesce(prev_object, next_object,
1411 prev_offset, next_offset,
1412 prev_size, next_size)
1413
1414 register vm_object_t prev_object;
1415 vm_object_t next_object;
1416 vm_offset_t prev_offset, next_offset;
1417 vm_size_t prev_size, next_size;
1418{
1419 vm_size_t newsize;
1420
1421#ifdef lint
1422 next_offset++;
1423#endif lint
1424
1425 if (next_object != NULL) {
1426 return(FALSE);
1427 }
1428
1429 if (prev_object == NULL) {
1430 return(TRUE);
1431 }
1432
1433 vm_object_lock(prev_object);
1434
1435 /*
1436 * Try to collapse the object first
1437 */
1438 vm_object_collapse(prev_object);
1439
1440 /*
1441 * Can't coalesce if:
1442 * . more than one reference
1443 * . paged out
1444 * . shadows another object
1445 * . has a copy elsewhere
1446 * (any of which mean that the pages not mapped to
1447 * prev_entry may be in use anyway)
1448 */
1449
1450 if (prev_object->ref_count > 1 ||
1451 prev_object->pager != NULL ||
1452 prev_object->shadow != NULL ||
1453 prev_object->copy != NULL) {
1454 vm_object_unlock(prev_object);
1455 return(FALSE);
1456 }
1457
1458 /*
1459 * Remove any pages that may still be in the object from
1460 * a previous deallocation.
1461 */
1462
1463 vm_object_page_remove(prev_object,
1464 prev_offset + prev_size,
1465 prev_offset + prev_size + next_size);
1466
1467 /*
1468 * Extend the object if necessary.
1469 */
1470 newsize = prev_offset + prev_size + next_size;
1471 if (newsize > prev_object->size)
1472 prev_object->size = newsize;
1473
1474 vm_object_unlock(prev_object);
1475 return(TRUE);
1476}
1477
e7345b2c 1478#ifdef DEBUG
15637ed4
RG
1479/*
1480 * vm_object_print: [ debug ]
1481 */
1482void vm_object_print(object, full)
1483 vm_object_t object;
1484 boolean_t full;
1485{
1486 register vm_page_t p;
1487 extern indent;
1488
1489 register int count;
1490
1491 if (object == NULL)
1492 return;
1493
1494 iprintf("Object 0x%x: size=0x%x, res=%d, ref=%d, ",
1495 (int) object, (int) object->size,
1496 object->resident_page_count, object->ref_count);
1497 printf("pager=0x%x+0x%x, shadow=(0x%x)+0x%x\n",
1498 (int) object->pager, (int) object->paging_offset,
1499 (int) object->shadow, (int) object->shadow_offset);
1500 printf("cache: next=0x%x, prev=0x%x\n",
1501 object->cached_list.next, object->cached_list.prev);
1502
1503 if (!full)
1504 return;
1505
1506 indent += 2;
1507 count = 0;
1508 p = (vm_page_t) queue_first(&object->memq);
1509 while (!queue_end(&object->memq, (queue_entry_t) p)) {
1510 if (count == 0)
1511 iprintf("memory:=");
1512 else if (count == 6) {
1513 printf("\n");
1514 iprintf(" ...");
1515 count = 0;
1516 } else
1517 printf(",");
1518 count++;
1519
1520 printf("(off=0x%x,page=0x%x)", p->offset, VM_PAGE_TO_PHYS(p));
1521 p = (vm_page_t) queue_next(&p->listq);
1522 }
1523 if (count != 0)
1524 printf("\n");
1525 indent -= 2;
1526}
e7345b2c 1527#endif /* DEBUG */