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