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