|
|
1.1 root 1: /*
2: * Mach Operating System
3: * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University.
4: * Copyright (c) 1993,1994 The University of Utah and
5: * the Computer Systems Laboratory (CSL).
6: * All rights reserved.
7: *
8: * Permission to use, copy, modify and distribute this software and its
9: * documentation is hereby granted, provided that both the copyright
10: * notice and this permission notice appear in all copies of the
11: * software, derivative works or modified versions, and any portions
12: * thereof, and that both notices appear in supporting documentation.
13: *
14: * CARNEGIE MELLON, THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF
15: * THIS SOFTWARE IN ITS "AS IS" CONDITION, AND DISCLAIM ANY LIABILITY
16: * OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF
17: * THIS SOFTWARE.
18: *
19: * Carnegie Mellon requests users of this software to return to
20: *
21: * Software Distribution Coordinator or [email protected]
22: * School of Computer Science
23: * Carnegie Mellon University
24: * Pittsburgh PA 15213-3890
25: *
26: * any improvements or extensions that they make and grant Carnegie Mellon
27: * the rights to redistribute these changes.
28: */
29: /*
30: * File: vm/vm_object.c
31: * Author: Avadis Tevanian, Jr., Michael Wayne Young
32: *
33: * Virtual memory object module.
34: */
35:
36: #include <norma_vm.h>
37: #include <mach_pagemap.h>
38:
39: #if NORMA_VM
40: #include <norma/xmm_server_rename.h>
41: #endif /* NORMA_VM */
42:
43: #include <mach/memory_object.h>
44: #include "memory_object_default.h"
45: #include "memory_object_user.h"
46: #include "vm_param.h"
47: #include <ipc/ipc_port.h>
48: #include <ipc/ipc_space.h>
49: #include <kern/assert.h>
50: #include <kern/lock.h>
51: #include <kern/queue.h>
52: #include <kern/zalloc.h>
53: #include <kern/debug.h>
54: #include <vm/memory_object.h>
55: #include <vm/vm_fault.h>
56: #include <vm/vm_map.h>
57: #include <vm/vm_object.h>
58: #include <vm/vm_page.h>
59: #include <vm/vm_pageout.h>
60:
61:
62: void memory_object_release(
63: ipc_port_t pager,
64: pager_request_t pager_request,
65: ipc_port_t pager_name); /* forward */
66:
67: void vm_object_deactivate_pages(vm_object_t);
68:
69: /*
70: * Virtual memory objects maintain the actual data
71: * associated with allocated virtual memory. A given
72: * page of memory exists within exactly one object.
73: *
74: * An object is only deallocated when all "references"
75: * are given up. Only one "reference" to a given
76: * region of an object should be writeable.
77: *
78: * Associated with each object is a list of all resident
79: * memory pages belonging to that object; this list is
80: * maintained by the "vm_page" module, but locked by the object's
81: * lock.
82: *
83: * Each object also records the memory object port
84: * that is used by the kernel to request and write
85: * back data (the memory object port, field "pager"),
86: * and the ports provided to the memory manager, the server that
87: * manages that data, to return data and control its
88: * use (the memory object control port, field "pager_request")
89: * and for naming (the memory object name port, field "pager_name").
90: *
91: * Virtual memory objects are allocated to provide
92: * zero-filled memory (vm_allocate) or map a user-defined
93: * memory object into a virtual address space (vm_map).
94: *
95: * Virtual memory objects that refer to a user-defined
96: * memory object are called "permanent", because all changes
97: * made in virtual memory are reflected back to the
98: * memory manager, which may then store it permanently.
99: * Other virtual memory objects are called "temporary",
100: * meaning that changes need be written back only when
101: * necessary to reclaim pages, and that storage associated
102: * with the object can be discarded once it is no longer
103: * mapped.
104: *
105: * A permanent memory object may be mapped into more
106: * than one virtual address space. Moreover, two threads
107: * may attempt to make the first mapping of a memory
108: * object concurrently. Only one thread is allowed to
109: * complete this mapping; all others wait for the
110: * "pager_initialized" field is asserted, indicating
111: * that the first thread has initialized all of the
112: * necessary fields in the virtual memory object structure.
113: *
114: * The kernel relies on a *default memory manager* to
115: * provide backing storage for the zero-filled virtual
116: * memory objects. The memory object ports associated
117: * with these temporary virtual memory objects are only
118: * generated and passed to the default memory manager
119: * when it becomes necessary. Virtual memory objects
120: * that depend on the default memory manager are called
121: * "internal". The "pager_created" field is provided to
122: * indicate whether these ports have ever been allocated.
123: *
124: * The kernel may also create virtual memory objects to
125: * hold changed pages after a copy-on-write operation.
126: * In this case, the virtual memory object (and its
127: * backing storage -- its memory object) only contain
128: * those pages that have been changed. The "shadow"
129: * field refers to the virtual memory object that contains
130: * the remainder of the contents. The "shadow_offset"
131: * field indicates where in the "shadow" these contents begin.
132: * The "copy" field refers to a virtual memory object
133: * to which changed pages must be copied before changing
134: * this object, in order to implement another form
135: * of copy-on-write optimization.
136: *
137: * The virtual memory object structure also records
138: * the attributes associated with its memory object.
139: * The "pager_ready", "can_persist" and "copy_strategy"
140: * fields represent those attributes. The "cached_list"
141: * field is used in the implementation of the persistence
142: * attribute.
143: *
144: * ZZZ Continue this comment.
145: */
146:
147: zone_t vm_object_zone; /* vm backing store zone */
148:
149: /*
150: * All wired-down kernel memory belongs to a single virtual
151: * memory object (kernel_object) to avoid wasting data structures.
152: */
153: vm_object_t kernel_object;
154:
155: /*
156: * Virtual memory objects that are not referenced by
157: * any address maps, but that are allowed to persist
158: * (an attribute specified by the associated memory manager),
159: * are kept in a queue (vm_object_cached_list).
160: *
161: * When an object from this queue is referenced again,
162: * for example to make another address space mapping,
163: * it must be removed from the queue. That is, the
164: * queue contains *only* objects with zero references.
165: *
166: * The kernel may choose to terminate objects from this
167: * queue in order to reclaim storage. The current policy
168: * is to permit a fixed maximum number of unreferenced
169: * objects (vm_object_cached_max).
170: *
171: * A simple lock (accessed by routines
172: * vm_object_cache_{lock,lock_try,unlock}) governs the
173: * object cache. It must be held when objects are
174: * added to or removed from the cache (in vm_object_terminate).
175: * The routines that acquire a reference to a virtual
176: * memory object based on one of the memory object ports
177: * must also lock the cache.
178: *
179: * Ideally, the object cache should be more isolated
180: * from the reference mechanism, so that the lock need
181: * not be held to make simple references.
182: */
183: queue_head_t vm_object_cached_list;
184: int vm_object_cached_count;
185: int vm_object_cached_max = 200; /* may be patched*/
186:
187: decl_simple_lock_data(,vm_object_cached_lock_data)
188:
189: #define vm_object_cache_lock() \
190: simple_lock(&vm_object_cached_lock_data)
191: #define vm_object_cache_lock_try() \
192: simple_lock_try(&vm_object_cached_lock_data)
193: #define vm_object_cache_unlock() \
194: simple_unlock(&vm_object_cached_lock_data)
195:
196: /*
197: * Virtual memory objects are initialized from
198: * a template (see vm_object_allocate).
199: *
200: * When adding a new field to the virtual memory
201: * object structure, be sure to add initialization
202: * (see vm_object_init).
203: */
204: vm_object_t vm_object_template;
205:
206: /*
207: * vm_object_allocate:
208: *
209: * Returns a new object with the given size.
210: */
211:
212: vm_object_t _vm_object_allocate(
213: vm_size_t size)
214: {
215: register vm_object_t object;
216:
217: object = (vm_object_t) zalloc(vm_object_zone);
218:
219: *object = *vm_object_template;
220: queue_init(&object->memq);
221: vm_object_lock_init(object);
222: object->size = size;
223:
224: return object;
225: }
226:
227: vm_object_t vm_object_allocate(
228: vm_size_t size)
229: {
230: register vm_object_t object;
231: register ipc_port_t port;
232:
233: object = _vm_object_allocate(size);
234: #if !NORMA_VM
235: port = ipc_port_alloc_kernel();
236: if (port == IP_NULL)
237: panic("vm_object_allocate");
238: object->pager_name = port;
239: ipc_kobject_set(port, (ipc_kobject_t) object, IKOT_PAGING_NAME);
240: #endif /* !NORMA_VM */
241:
242: return object;
243: }
244:
245: /*
246: * vm_object_bootstrap:
247: *
248: * Initialize the VM objects module.
249: */
250: void vm_object_bootstrap(void)
251: {
252: vm_object_zone = zinit((vm_size_t) sizeof(struct vm_object),
253: round_page(512*1024),
254: round_page(12*1024),
255: 0, "objects");
256:
257: queue_init(&vm_object_cached_list);
258: simple_lock_init(&vm_object_cached_lock_data);
259:
260: /*
261: * Fill in a template object, for quick initialization
262: */
263:
264: vm_object_template = (vm_object_t) zalloc(vm_object_zone);
265: bzero((char *) vm_object_template, sizeof *vm_object_template);
266:
267: vm_object_template->ref_count = 1;
268: vm_object_template->size = 0;
269: vm_object_template->resident_page_count = 0;
270: vm_object_template->copy = VM_OBJECT_NULL;
271: vm_object_template->shadow = VM_OBJECT_NULL;
272: vm_object_template->shadow_offset = (vm_offset_t) 0;
273:
274: vm_object_template->pager = IP_NULL;
275: vm_object_template->paging_offset = 0;
276: vm_object_template->pager_request = PAGER_REQUEST_NULL;
277: vm_object_template->pager_name = IP_NULL;
278:
279: vm_object_template->pager_created = FALSE;
280: vm_object_template->pager_initialized = FALSE;
281: vm_object_template->pager_ready = FALSE;
282:
283: vm_object_template->copy_strategy = MEMORY_OBJECT_COPY_NONE;
284: /* ignored if temporary, will be reset before
285: * permanent object becomes ready */
286: vm_object_template->use_shared_copy = FALSE;
287: vm_object_template->shadowed = FALSE;
288:
289: vm_object_template->absent_count = 0;
290: vm_object_template->all_wanted = 0; /* all bits FALSE */
291:
292: vm_object_template->paging_in_progress = 0;
293: vm_object_template->can_persist = FALSE;
294: vm_object_template->internal = TRUE;
295: vm_object_template->temporary = TRUE;
296: vm_object_template->alive = TRUE;
297: vm_object_template->lock_in_progress = FALSE;
298: vm_object_template->lock_restart = FALSE;
299: vm_object_template->use_old_pageout = TRUE; /* XXX change later */
300: vm_object_template->last_alloc = (vm_offset_t) 0;
301:
302: #if MACH_PAGEMAP
303: vm_object_template->existence_info = VM_EXTERNAL_NULL;
304: #endif /* MACH_PAGEMAP */
305:
306: /*
307: * Initialize the "kernel object"
308: */
309:
310: kernel_object = _vm_object_allocate(
311: VM_MAX_KERNEL_ADDRESS - VM_MIN_KERNEL_ADDRESS);
312:
313: /*
314: * Initialize the "submap object". Make it as large as the
315: * kernel object so that no limit is imposed on submap sizes.
316: */
317:
318: vm_submap_object = _vm_object_allocate(
319: VM_MAX_KERNEL_ADDRESS - VM_MIN_KERNEL_ADDRESS);
320:
321: #if MACH_PAGEMAP
322: vm_external_module_initialize();
323: #endif /* MACH_PAGEMAP */
324: }
325:
326: void vm_object_init(void)
327: {
328: #if !NORMA_VM
329: /*
330: * Finish initializing the kernel object.
331: * The submap object doesn't need a name port.
332: */
333:
334: kernel_object->pager_name = ipc_port_alloc_kernel();
335: ipc_kobject_set(kernel_object->pager_name,
336: (ipc_kobject_t) kernel_object,
337: IKOT_PAGING_NAME);
338: #endif /* !NORMA_VM */
339: }
340:
341: /*
342: * vm_object_reference:
343: *
344: * Gets another reference to the given object.
345: */
346: void vm_object_reference(
347: register vm_object_t object)
348: {
349: if (object == VM_OBJECT_NULL)
350: return;
351:
352: vm_object_lock(object);
353: assert(object->ref_count > 0);
354: object->ref_count++;
355: vm_object_unlock(object);
356: }
357:
358: /*
359: * vm_object_deallocate:
360: *
361: * Release a reference to the specified object,
362: * gained either through a vm_object_allocate
363: * or a vm_object_reference call. When all references
364: * are gone, storage associated with this object
365: * may be relinquished.
366: *
367: * No object may be locked.
368: */
369: void vm_object_deallocate(
370: register vm_object_t object)
371: {
372: vm_object_t temp;
373:
374: while (object != VM_OBJECT_NULL) {
375:
376: /*
377: * The cache holds a reference (uncounted) to
378: * the object; we must lock it before removing
379: * the object.
380: */
381:
382: vm_object_cache_lock();
383:
384: /*
385: * Lose the reference
386: */
387: vm_object_lock(object);
388: if (--(object->ref_count) > 0) {
389:
390: /*
391: * If there are still references, then
392: * we are done.
393: */
394: vm_object_unlock(object);
395: vm_object_cache_unlock();
396: return;
397: }
398:
399: /*
400: * See whether this object can persist. If so, enter
401: * it in the cache, then deactivate all of its
402: * pages.
403: */
404: if (object->can_persist) {
405: boolean_t overflow;
406:
407: /*
408: * Enter the object onto the queue
409: * of "cached" objects. Remember whether
410: * we've caused the queue to overflow,
411: * as a hint.
412: */
413:
414: queue_enter(&vm_object_cached_list, object,
415: vm_object_t, cached_list);
416: overflow = (++vm_object_cached_count > vm_object_cached_max);
417: vm_object_cache_unlock();
418:
419: vm_object_deactivate_pages(object);
420: vm_object_unlock(object);
421:
422: /*
423: * If we didn't overflow, or if the queue has
424: * been reduced back to below the specified
425: * minimum, then quit.
426: */
427: if (!overflow)
428: return;
429:
430: while (TRUE) {
431: vm_object_cache_lock();
432: if (vm_object_cached_count <=
433: vm_object_cached_max) {
434: vm_object_cache_unlock();
435: return;
436: }
437:
438: /*
439: * If we must trim down the queue, take
440: * the first object, and proceed to
441: * terminate it instead of the original
442: * object. Have to wait for pager init.
443: * if it's in progress.
444: */
445: object= (vm_object_t)
446: queue_first(&vm_object_cached_list);
447: vm_object_lock(object);
448:
449: if (!(object->pager_created &&
450: !object->pager_initialized)) {
451:
452: /*
453: * Ok to terminate, hang on to lock.
454: */
455: break;
456: }
457:
458: vm_object_assert_wait(object,
459: VM_OBJECT_EVENT_INITIALIZED, FALSE);
460: vm_object_unlock(object);
461: vm_object_cache_unlock();
462: thread_block((void (*)()) 0);
463:
464: /*
465: * Continue loop to check if cache still
466: * needs to be trimmed.
467: */
468: }
469:
470: /*
471: * Actually remove object from cache.
472: */
473:
474: queue_remove(&vm_object_cached_list, object,
475: vm_object_t, cached_list);
476: vm_object_cached_count--;
477:
478: assert(object->ref_count == 0);
479: }
480: else {
481: if (object->pager_created &&
482: !object->pager_initialized) {
483:
484: /*
485: * Have to wait for initialization.
486: * Put reference back and retry
487: * when it's initialized.
488: */
489: object->ref_count++;
490: vm_object_assert_wait(object,
491: VM_OBJECT_EVENT_INITIALIZED, FALSE);
492: vm_object_unlock(object);
493: vm_object_cache_unlock();
494: thread_block((void (*)()) 0);
495: continue;
496: }
497: }
498:
499: /*
500: * Take the reference to the shadow object
501: * out of the object to be destroyed.
502: */
503:
504: temp = object->shadow;
505:
506: /*
507: * Destroy the object; the cache lock will
508: * be released in the process.
509: */
510:
511: vm_object_terminate(object);
512:
513: /*
514: * Deallocate the reference to the shadow
515: * by continuing the loop with that object
516: * in place of the original.
517: */
518:
519: object = temp;
520: }
521: }
522:
523: boolean_t vm_object_terminate_remove_all = FALSE;
524:
525: /*
526: * Routine: vm_object_terminate
527: * Purpose:
528: * Free all resources associated with a vm_object.
529: * In/out conditions:
530: * Upon entry, the object and the cache must be locked,
531: * and the object must have no references.
532: *
533: * The shadow object reference is left alone.
534: *
535: * Upon exit, the cache will be unlocked, and the
536: * object will cease to exist.
537: */
538: void vm_object_terminate(
539: register vm_object_t object)
540: {
541: register vm_page_t p;
542: vm_object_t shadow_object;
543:
544: /*
545: * Make sure the object isn't already being terminated
546: */
547:
548: assert(object->alive);
549: object->alive = FALSE;
550:
551: /*
552: * Make sure no one can look us up now.
553: */
554:
555: vm_object_remove(object);
556: vm_object_cache_unlock();
557:
558: /*
559: * Detach the object from its shadow if we are the shadow's
560: * copy.
561: */
562: if ((shadow_object = object->shadow) != VM_OBJECT_NULL) {
563: vm_object_lock(shadow_object);
564: assert((shadow_object->copy == object) ||
565: (shadow_object->copy == VM_OBJECT_NULL));
566: shadow_object->copy = VM_OBJECT_NULL;
567: vm_object_unlock(shadow_object);
568: }
569:
570: /*
571: * The pageout daemon might be playing with our pages.
572: * Now that the object is dead, it won't touch any more
573: * pages, but some pages might already be on their way out.
574: * Hence, we wait until the active paging activities have ceased.
575: */
576:
577: vm_object_paging_wait(object, FALSE);
578:
579: /*
580: * Clean or free the pages, as appropriate.
581: * It is possible for us to find busy/absent pages,
582: * if some faults on this object were aborted.
583: */
584:
585: if ((object->temporary) || (object->pager == IP_NULL)) {
586: while (!queue_empty(&object->memq)) {
587: p = (vm_page_t) queue_first(&object->memq);
588:
589: VM_PAGE_CHECK(p);
590:
591: if (p->busy && !p->absent)
592: panic("vm_object_terminate.2 0x%x 0x%x",
593: object, p);
594:
595: VM_PAGE_FREE(p);
596: }
597: } else while (!queue_empty(&object->memq)) {
598: p = (vm_page_t) queue_first(&object->memq);
599:
600: VM_PAGE_CHECK(p);
601:
602: if (p->busy && !p->absent)
603: panic("vm_object_terminate.3 0x%x 0x%x", object, p);
604:
605: vm_page_lock_queues();
606: VM_PAGE_QUEUES_REMOVE(p);
607: vm_page_unlock_queues();
608:
609: if (p->absent || p->private) {
610:
611: /*
612: * For private pages, VM_PAGE_FREE just
613: * leaves the page structure around for
614: * its owner to clean up. For absent
615: * pages, the structure is returned to
616: * the appropriate pool.
617: */
618:
619: goto free_page;
620: }
621:
622: if (p->fictitious)
623: panic("vm_object_terminate.4 0x%x 0x%x", object, p);
624:
625: if (!p->dirty)
626: p->dirty = pmap_is_modified(p->phys_addr);
627:
628: if (p->dirty || p->precious) {
629: p->busy = TRUE;
630: vm_pageout_page(p, FALSE, TRUE); /* flush page */
631: } else {
632: free_page:
633: VM_PAGE_FREE(p);
634: }
635: }
636:
637: assert(object->ref_count == 0);
638: assert(object->paging_in_progress == 0);
639:
640: /*
641: * Throw away port rights... note that they may
642: * already have been thrown away (by vm_object_destroy
643: * or memory_object_destroy).
644: *
645: * Instead of destroying the control and name ports,
646: * we send all rights off to the memory manager instead,
647: * using memory_object_terminate.
648: */
649:
650: vm_object_unlock(object);
651:
652: if (object->pager != IP_NULL) {
653: /* consumes our rights for pager, pager_request, pager_name */
654: memory_object_release(object->pager,
655: object->pager_request,
656: object->pager_name);
657: } else if (object->pager_name != IP_NULL) {
658: /* consumes our right for pager_name */
659: #if NORMA_VM
660: ipc_port_release_send(object->pager_name);
661: #else /* NORMA_VM */
662: ipc_port_dealloc_kernel(object->pager_name);
663: #endif /* NORMA_VM */
664: }
665:
666: #if MACH_PAGEMAP
667: vm_external_destroy(object->existence_info);
668: #endif /* MACH_PAGEMAP */
669:
670: /*
671: * Free the space for the object.
672: */
673:
674: zfree(vm_object_zone, (vm_offset_t) object);
675: }
676:
677: /*
678: * Routine: vm_object_pager_wakeup
679: * Purpose: Wake up anyone waiting for IKOT_PAGER_TERMINATING
680: */
681:
682: void
683: vm_object_pager_wakeup(
684: ipc_port_t pager)
685: {
686: boolean_t someone_waiting;
687:
688: /*
689: * If anyone was waiting for the memory_object_terminate
690: * to be queued, wake them up now.
691: */
692: vm_object_cache_lock();
693: assert(ip_kotype(pager) == IKOT_PAGER_TERMINATING);
694: someone_waiting = (pager->ip_kobject != IKO_NULL);
695: if (ip_active(pager))
696: ipc_kobject_set(pager, IKO_NULL, IKOT_NONE);
697: vm_object_cache_unlock();
698: if (someone_waiting) {
699: thread_wakeup((event_t) pager);
700: }
701: }
702:
703: /*
704: * Routine: memory_object_release
705: * Purpose: Terminate the pager and release port rights,
706: * just like memory_object_terminate, except
707: * that we wake up anyone blocked in vm_object_enter
708: * waiting for termination message to be queued
709: * before calling memory_object_init.
710: */
711: void memory_object_release(
712: ipc_port_t pager,
713: pager_request_t pager_request,
714: ipc_port_t pager_name)
715: {
716:
717: /*
718: * Keep a reference to pager port;
719: * the terminate might otherwise release all references.
720: */
721: ip_reference(pager);
722:
723: /*
724: * Terminate the pager.
725: */
726: (void) memory_object_terminate(pager, pager_request, pager_name);
727:
728: /*
729: * Wakeup anyone waiting for this terminate
730: */
731: vm_object_pager_wakeup(pager);
732:
733: /*
734: * Release reference to pager port.
735: */
736: ip_release(pager);
737: }
738:
739: /*
740: * Routine: vm_object_abort_activity [internal use only]
741: * Purpose:
742: * Abort paging requests pending on this object.
743: * In/out conditions:
744: * The object is locked on entry and exit.
745: */
746: void vm_object_abort_activity(
747: vm_object_t object)
748: {
749: register
750: vm_page_t p;
751: vm_page_t next;
752:
753: /*
754: * Abort all activity that would be waiting
755: * for a result on this memory object.
756: *
757: * We could also choose to destroy all pages
758: * that we have in memory for this object, but
759: * we don't.
760: */
761:
762: p = (vm_page_t) queue_first(&object->memq);
763: while (!queue_end(&object->memq, (queue_entry_t) p)) {
764: next = (vm_page_t) queue_next(&p->listq);
765:
766: /*
767: * If it's being paged in, destroy it.
768: * If an unlock has been requested, start it again.
769: */
770:
771: if (p->busy && p->absent) {
772: VM_PAGE_FREE(p);
773: }
774: else {
775: if (p->unlock_request != VM_PROT_NONE)
776: p->unlock_request = VM_PROT_NONE;
777: PAGE_WAKEUP(p);
778: }
779:
780: p = next;
781: }
782:
783: /*
784: * Wake up threads waiting for the memory object to
785: * become ready.
786: */
787:
788: object->pager_ready = TRUE;
789: vm_object_wakeup(object, VM_OBJECT_EVENT_PAGER_READY);
790: }
791:
792: /*
793: * Routine: memory_object_destroy [user interface]
794: * Purpose:
795: * Shut down a memory object, despite the
796: * presence of address map (or other) references
797: * to the vm_object.
798: * Note:
799: * This routine may be called either from the user interface,
800: * or from port destruction handling (via vm_object_destroy).
801: */
802: kern_return_t memory_object_destroy(
803: register
804: vm_object_t object,
805: kern_return_t reason)
806: {
807: ipc_port_t old_object, old_name;
808: pager_request_t old_control;
809:
810: #ifdef lint
811: reason++;
812: #endif /* lint */
813:
814: if (object == VM_OBJECT_NULL)
815: return KERN_SUCCESS;
816:
817: /*
818: * Remove the port associations immediately.
819: *
820: * This will prevent the memory manager from further
821: * meddling. [If it wanted to flush data or make
822: * other changes, it should have done so before performing
823: * the destroy call.]
824: */
825:
826: vm_object_cache_lock();
827: vm_object_lock(object);
828: vm_object_remove(object);
829: object->can_persist = FALSE;
830: vm_object_cache_unlock();
831:
832: /*
833: * Rip out the ports from the vm_object now... this
834: * will prevent new memory_object calls from succeeding.
835: */
836:
837: old_object = object->pager;
838: object->pager = IP_NULL;
839:
840: old_control = object->pager_request;
841: object->pager_request = PAGER_REQUEST_NULL;
842:
843: old_name = object->pager_name;
844: object->pager_name = IP_NULL;
845:
846:
847: /*
848: * Wait for existing paging activity (that might
849: * have the old ports) to subside.
850: */
851:
852: vm_object_paging_wait(object, FALSE);
853: vm_object_unlock(object);
854:
855: /*
856: * Shut down the ports now.
857: *
858: * [Paging operations may be proceeding concurrently --
859: * they'll get the null values established above.]
860: */
861:
862: if (old_object != IP_NULL) {
863: /* consumes our rights for object, control, name */
864: memory_object_release(old_object, old_control,
865: old_name);
866: } else if (old_name != IP_NULL) {
867: /* consumes our right for name */
868: #if NORMA_VM
869: ipc_port_release_send(object->pager_name);
870: #else /* NORMA_VM */
871: ipc_port_dealloc_kernel(object->pager_name);
872: #endif /* NORMA_VM */
873: }
874:
875: /*
876: * Lose the reference that was donated for this routine
877: */
878:
879: vm_object_deallocate(object);
880:
881: return KERN_SUCCESS;
882: }
883:
884: /*
885: * vm_object_deactivate_pages
886: *
887: * Deactivate all pages in the specified object. (Keep its pages
888: * in memory even though it is no longer referenced.)
889: *
890: * The object must be locked.
891: */
892: void vm_object_deactivate_pages(
893: register vm_object_t object)
894: {
895: register vm_page_t p;
896:
897: queue_iterate(&object->memq, p, vm_page_t, listq) {
898: vm_page_lock_queues();
899: if (!p->busy)
900: vm_page_deactivate(p);
901: vm_page_unlock_queues();
902: }
903: }
904:
905:
906: /*
907: * Routine: vm_object_pmap_protect
908: *
909: * Purpose:
910: * Reduces the permission for all physical
911: * pages in the specified object range.
912: *
913: * If removing write permission only, it is
914: * sufficient to protect only the pages in
915: * the top-level object; only those pages may
916: * have write permission.
917: *
918: * If removing all access, we must follow the
919: * shadow chain from the top-level object to
920: * remove access to all pages in shadowed objects.
921: *
922: * The object must *not* be locked. The object must
923: * be temporary/internal.
924: *
925: * If pmap is not NULL, this routine assumes that
926: * the only mappings for the pages are in that
927: * pmap.
928: */
929: boolean_t vm_object_pmap_protect_by_page = FALSE;
930:
931: void vm_object_pmap_protect(
932: register vm_object_t object,
933: register vm_offset_t offset,
934: vm_offset_t size,
935: pmap_t pmap,
936: vm_offset_t pmap_start,
937: vm_prot_t prot)
938: {
939: if (object == VM_OBJECT_NULL)
940: return;
941:
942: vm_object_lock(object);
943:
944: assert(object->temporary && object->internal);
945:
946: while (TRUE) {
947: if (object->resident_page_count > atop(size) / 2 &&
948: pmap != PMAP_NULL) {
949: vm_object_unlock(object);
950: pmap_protect(pmap, pmap_start, pmap_start + size, prot);
951: return;
952: }
953:
954: {
955: register vm_page_t p;
956: register vm_offset_t end;
957:
958: end = offset + size;
959:
960: queue_iterate(&object->memq, p, vm_page_t, listq) {
961: if (!p->fictitious &&
962: (offset <= p->offset) &&
963: (p->offset < end)) {
964: if ((pmap == PMAP_NULL) ||
965: vm_object_pmap_protect_by_page) {
966: pmap_page_protect(p->phys_addr,
967: prot & ~p->page_lock);
968: } else {
969: vm_offset_t start =
970: pmap_start +
971: (p->offset - offset);
972:
973: pmap_protect(pmap,
974: start,
975: start + PAGE_SIZE,
976: prot);
977: }
978: }
979: }
980: }
981:
982: if (prot == VM_PROT_NONE) {
983: /*
984: * Must follow shadow chain to remove access
985: * to pages in shadowed objects.
986: */
987: register vm_object_t next_object;
988:
989: next_object = object->shadow;
990: if (next_object != VM_OBJECT_NULL) {
991: offset += object->shadow_offset;
992: vm_object_lock(next_object);
993: vm_object_unlock(object);
994: object = next_object;
995: }
996: else {
997: /*
998: * End of chain - we are done.
999: */
1000: break;
1001: }
1002: }
1003: else {
1004: /*
1005: * Pages in shadowed objects may never have
1006: * write permission - we may stop here.
1007: */
1008: break;
1009: }
1010: }
1011:
1012: vm_object_unlock(object);
1013: }
1014:
1015: /*
1016: * vm_object_pmap_remove:
1017: *
1018: * Removes all physical pages in the specified
1019: * object range from all physical maps.
1020: *
1021: * The object must *not* be locked.
1022: */
1023: void vm_object_pmap_remove(
1024: register vm_object_t object,
1025: register vm_offset_t start,
1026: register vm_offset_t end)
1027: {
1028: register vm_page_t p;
1029:
1030: if (object == VM_OBJECT_NULL)
1031: return;
1032:
1033: vm_object_lock(object);
1034: queue_iterate(&object->memq, p, vm_page_t, listq) {
1035: if (!p->fictitious &&
1036: (start <= p->offset) &&
1037: (p->offset < end))
1038: pmap_page_protect(p->phys_addr, VM_PROT_NONE);
1039: }
1040: vm_object_unlock(object);
1041: }
1042:
1043: /*
1044: * Routine: vm_object_copy_slowly
1045: *
1046: * Description:
1047: * Copy the specified range of the source
1048: * virtual memory object without using
1049: * protection-based optimizations (such
1050: * as copy-on-write). The pages in the
1051: * region are actually copied.
1052: *
1053: * In/out conditions:
1054: * The caller must hold a reference and a lock
1055: * for the source virtual memory object. The source
1056: * object will be returned *unlocked*.
1057: *
1058: * Results:
1059: * If the copy is completed successfully, KERN_SUCCESS is
1060: * returned. If the caller asserted the interruptible
1061: * argument, and an interruption occurred while waiting
1062: * for a user-generated event, MACH_SEND_INTERRUPTED is
1063: * returned. Other values may be returned to indicate
1064: * hard errors during the copy operation.
1065: *
1066: * A new virtual memory object is returned in a
1067: * parameter (_result_object). The contents of this
1068: * new object, starting at a zero offset, are a copy
1069: * of the source memory region. In the event of
1070: * an error, this parameter will contain the value
1071: * VM_OBJECT_NULL.
1072: */
1073: kern_return_t vm_object_copy_slowly(
1074: register
1075: vm_object_t src_object,
1076: vm_offset_t src_offset,
1077: vm_size_t size,
1078: boolean_t interruptible,
1079: vm_object_t *_result_object) /* OUT */
1080: {
1081: vm_object_t new_object;
1082: vm_offset_t new_offset;
1083:
1084: if (size == 0) {
1085: vm_object_unlock(src_object);
1086: *_result_object = VM_OBJECT_NULL;
1087: return KERN_INVALID_ARGUMENT;
1088: }
1089:
1090: /*
1091: * Prevent destruction of the source object while we copy.
1092: */
1093:
1094: assert(src_object->ref_count > 0);
1095: src_object->ref_count++;
1096: vm_object_unlock(src_object);
1097:
1098: /*
1099: * Create a new object to hold the copied pages.
1100: * A few notes:
1101: * We fill the new object starting at offset 0,
1102: * regardless of the input offset.
1103: * We don't bother to lock the new object within
1104: * this routine, since we have the only reference.
1105: */
1106:
1107: new_object = vm_object_allocate(size);
1108: new_offset = 0;
1109:
1110: assert(size == trunc_page(size)); /* Will the loop terminate? */
1111:
1112: for ( ;
1113: size != 0 ;
1114: src_offset += PAGE_SIZE, new_offset += PAGE_SIZE, size -= PAGE_SIZE
1115: ) {
1116: vm_page_t new_page;
1117: vm_fault_return_t result;
1118:
1119: while ((new_page = vm_page_alloc(new_object, new_offset))
1120: == VM_PAGE_NULL) {
1121: VM_PAGE_WAIT((void (*)()) 0);
1122: }
1123:
1124: do {
1125: vm_prot_t prot = VM_PROT_READ;
1126: vm_page_t _result_page;
1127: vm_page_t top_page;
1128: register
1129: vm_page_t result_page;
1130:
1131: vm_object_lock(src_object);
1132: src_object->paging_in_progress++;
1133:
1134: result = vm_fault_page(src_object, src_offset,
1135: VM_PROT_READ, FALSE, interruptible,
1136: &prot, &_result_page, &top_page,
1137: FALSE, (void (*)()) 0);
1138:
1139: switch(result) {
1140: case VM_FAULT_SUCCESS:
1141: result_page = _result_page;
1142:
1143: /*
1144: * We don't need to hold the object
1145: * lock -- the busy page will be enough.
1146: * [We don't care about picking up any
1147: * new modifications.]
1148: *
1149: * Copy the page to the new object.
1150: *
1151: * POLICY DECISION:
1152: * If result_page is clean,
1153: * we could steal it instead
1154: * of copying.
1155: */
1156:
1157: vm_object_unlock(result_page->object);
1158: vm_page_copy(result_page, new_page);
1159:
1160: /*
1161: * Let go of both pages (make them
1162: * not busy, perform wakeup, activate).
1163: */
1164:
1165: new_page->busy = FALSE;
1166: new_page->dirty = TRUE;
1167: vm_object_lock(result_page->object);
1168: PAGE_WAKEUP_DONE(result_page);
1169:
1170: vm_page_lock_queues();
1171: if (!result_page->active &&
1172: !result_page->inactive)
1173: vm_page_activate(result_page);
1174: vm_page_activate(new_page);
1175: vm_page_unlock_queues();
1176:
1177: /*
1178: * Release paging references and
1179: * top-level placeholder page, if any.
1180: */
1181:
1182: vm_fault_cleanup(result_page->object,
1183: top_page);
1184:
1185: break;
1186:
1187: case VM_FAULT_RETRY:
1188: break;
1189:
1190: case VM_FAULT_MEMORY_SHORTAGE:
1191: VM_PAGE_WAIT((void (*)()) 0);
1192: break;
1193:
1194: case VM_FAULT_FICTITIOUS_SHORTAGE:
1195: vm_page_more_fictitious();
1196: break;
1197:
1198: case VM_FAULT_INTERRUPTED:
1199: vm_page_free(new_page);
1200: vm_object_deallocate(new_object);
1201: vm_object_deallocate(src_object);
1202: *_result_object = VM_OBJECT_NULL;
1203: return MACH_SEND_INTERRUPTED;
1204:
1205: case VM_FAULT_MEMORY_ERROR:
1206: /*
1207: * A policy choice:
1208: * (a) ignore pages that we can't
1209: * copy
1210: * (b) return the null object if
1211: * any page fails [chosen]
1212: */
1213:
1214: vm_page_free(new_page);
1215: vm_object_deallocate(new_object);
1216: vm_object_deallocate(src_object);
1217: *_result_object = VM_OBJECT_NULL;
1218: return KERN_MEMORY_ERROR;
1219: }
1220: } while (result != VM_FAULT_SUCCESS);
1221: }
1222:
1223: /*
1224: * Lose the extra reference, and return our object.
1225: */
1226:
1227: vm_object_deallocate(src_object);
1228: *_result_object = new_object;
1229: return KERN_SUCCESS;
1230: }
1231:
1232: /*
1233: * Routine: vm_object_copy_temporary
1234: *
1235: * Purpose:
1236: * Copy the specified range of the source virtual
1237: * memory object, if it can be done without blocking.
1238: *
1239: * Results:
1240: * If the copy is successful, the copy is returned in
1241: * the arguments; otherwise, the arguments are not
1242: * affected.
1243: *
1244: * In/out conditions:
1245: * The object should be unlocked on entry and exit.
1246: */
1247:
1248: vm_object_t vm_object_copy_delayed(); /* forward declaration */
1249:
1250: boolean_t vm_object_copy_temporary(
1251: vm_object_t *_object, /* INOUT */
1252: vm_offset_t *_offset, /* INOUT */
1253: boolean_t *_src_needs_copy, /* OUT */
1254: boolean_t *_dst_needs_copy) /* OUT */
1255: {
1256: vm_object_t object = *_object;
1257:
1258: #ifdef lint
1259: ++*_offset;
1260: #endif /* lint */
1261:
1262: if (object == VM_OBJECT_NULL) {
1263: *_src_needs_copy = FALSE;
1264: *_dst_needs_copy = FALSE;
1265: return TRUE;
1266: }
1267:
1268: /*
1269: * If the object is temporary, we can perform
1270: * a symmetric copy-on-write without asking.
1271: */
1272:
1273: vm_object_lock(object);
1274: if (object->temporary) {
1275:
1276: /*
1277: * Shared objects use delayed copy
1278: */
1279: if (object->use_shared_copy) {
1280:
1281: /*
1282: * Asymmetric copy strategy. Destination
1283: * must be copied (to allow copy object reuse).
1284: * Source is unaffected.
1285: */
1286: vm_object_unlock(object);
1287: object = vm_object_copy_delayed(object);
1288: *_object = object;
1289: *_src_needs_copy = FALSE;
1290: *_dst_needs_copy = TRUE;
1291: return TRUE;
1292: }
1293:
1294: /*
1295: * Make another reference to the object.
1296: *
1297: * Leave object/offset unchanged.
1298: */
1299:
1300: assert(object->ref_count > 0);
1301: object->ref_count++;
1302: object->shadowed = TRUE;
1303: vm_object_unlock(object);
1304:
1305: /*
1306: * Both source and destination must make
1307: * shadows, and the source must be made
1308: * read-only if not already.
1309: */
1310:
1311: *_src_needs_copy = TRUE;
1312: *_dst_needs_copy = TRUE;
1313: return TRUE;
1314: }
1315:
1316: if (object->pager_ready &&
1317: (object->copy_strategy == MEMORY_OBJECT_COPY_DELAY)) {
1318: /* XXX Do something intelligent (see temporary code above) */
1319: }
1320: vm_object_unlock(object);
1321:
1322: return FALSE;
1323: }
1324:
1325: /*
1326: * Routine: vm_object_copy_call [internal]
1327: *
1328: * Description:
1329: * Copy the specified (src_offset, size) portion
1330: * of the source object (src_object), using the
1331: * user-managed copy algorithm.
1332: *
1333: * In/out conditions:
1334: * The source object must be locked on entry. It
1335: * will be *unlocked* on exit.
1336: *
1337: * Results:
1338: * If the copy is successful, KERN_SUCCESS is returned.
1339: * This routine is interruptible; if a wait for
1340: * a user-generated event is interrupted, MACH_SEND_INTERRUPTED
1341: * is returned. Other return values indicate hard errors
1342: * in creating the user-managed memory object for the copy.
1343: *
1344: * A new object that represents the copied virtual
1345: * memory is returned in a parameter (*_result_object).
1346: * If the return value indicates an error, this parameter
1347: * is not valid.
1348: */
1349: kern_return_t vm_object_copy_call(
1350: vm_object_t src_object,
1351: vm_offset_t src_offset,
1352: vm_size_t size,
1353: vm_object_t *_result_object) /* OUT */
1354: {
1355: vm_offset_t src_end = src_offset + size;
1356: ipc_port_t new_memory_object;
1357: vm_object_t new_object;
1358: vm_page_t p;
1359:
1360: /*
1361: * Set the backing object for the new
1362: * temporary object.
1363: */
1364:
1365: assert(src_object->ref_count > 0);
1366: src_object->ref_count++;
1367: vm_object_paging_begin(src_object);
1368: vm_object_unlock(src_object);
1369:
1370: /*
1371: * Create a memory object port to be associated
1372: * with this new vm_object.
1373: *
1374: * Since the kernel has the only rights to this
1375: * port, we need not hold the cache lock.
1376: *
1377: * Since we have the only object reference, we
1378: * need not be worried about collapse operations.
1379: *
1380: */
1381:
1382: new_memory_object = ipc_port_alloc_kernel();
1383: if (new_memory_object == IP_NULL) {
1384: panic("vm_object_copy_call: allocate memory object port");
1385: /* XXX Shouldn't panic here. */
1386: }
1387:
1388: /* we hold a naked receive right for new_memory_object */
1389: (void) ipc_port_make_send(new_memory_object);
1390: /* now we also hold a naked send right for new_memory_object */
1391:
1392: /*
1393: * Let the memory manager know that a copy operation
1394: * is in progress. Note that we're using the old
1395: * memory object's ports (for which we're holding
1396: * a paging reference)... the memory manager cannot
1397: * yet affect the new memory object.
1398: */
1399:
1400: (void) memory_object_copy(src_object->pager,
1401: src_object->pager_request,
1402: src_offset, size,
1403: new_memory_object);
1404: /* no longer hold the naked receive right for new_memory_object */
1405:
1406: vm_object_lock(src_object);
1407: vm_object_paging_end(src_object);
1408:
1409: /*
1410: * Remove write access from all of the pages of
1411: * the old memory object that we can.
1412: */
1413:
1414: queue_iterate(&src_object->memq, p, vm_page_t, listq) {
1415: if (!p->fictitious &&
1416: (src_offset <= p->offset) &&
1417: (p->offset < src_end) &&
1418: !(p->page_lock & VM_PROT_WRITE)) {
1419: p->page_lock |= VM_PROT_WRITE;
1420: pmap_page_protect(p->phys_addr, VM_PROT_ALL & ~p->page_lock);
1421: }
1422: }
1423:
1424: vm_object_unlock(src_object);
1425:
1426: /*
1427: * Initialize the rest of the paging stuff
1428: */
1429:
1430: new_object = vm_object_enter(new_memory_object, size, FALSE);
1431: new_object->shadow = src_object;
1432: new_object->shadow_offset = src_offset;
1433:
1434: /*
1435: * Drop the reference for new_memory_object taken above.
1436: */
1437:
1438: ipc_port_release_send(new_memory_object);
1439: /* no longer hold the naked send right for new_memory_object */
1440:
1441: *_result_object = new_object;
1442: return KERN_SUCCESS;
1443: }
1444:
1445: /*
1446: * Routine: vm_object_copy_delayed [internal]
1447: *
1448: * Description:
1449: * Copy the specified virtual memory object, using
1450: * the asymmetric copy-on-write algorithm.
1451: *
1452: * In/out conditions:
1453: * The object must be unlocked on entry.
1454: *
1455: * This routine will not block waiting for user-generated
1456: * events. It is not interruptible.
1457: */
1458: vm_object_t vm_object_copy_delayed(
1459: vm_object_t src_object)
1460: {
1461: vm_object_t new_copy;
1462: vm_object_t old_copy;
1463: vm_page_t p;
1464:
1465: /*
1466: * The user-level memory manager wants to see
1467: * all of the changes to this object, but it
1468: * has promised not to make any changes on its own.
1469: *
1470: * Perform an asymmetric copy-on-write, as follows:
1471: * Create a new object, called a "copy object"
1472: * to hold pages modified by the new mapping
1473: * (i.e., the copy, not the original mapping).
1474: * Record the original object as the backing
1475: * object for the copy object. If the
1476: * original mapping does not change a page,
1477: * it may be used read-only by the copy.
1478: * Record the copy object in the original
1479: * object. When the original mapping causes
1480: * a page to be modified, it must be copied
1481: * to a new page that is "pushed" to the
1482: * copy object.
1483: * Mark the new mapping (the copy object)
1484: * copy-on-write. This makes the copy
1485: * object itself read-only, allowing it
1486: * to be reused if the original mapping
1487: * makes no changes, and simplifying the
1488: * synchronization required in the "push"
1489: * operation described above.
1490: *
1491: * The copy-on-write is said to be assymetric because
1492: * the original object is *not* marked copy-on-write.
1493: * A copied page is pushed to the copy object, regardless
1494: * which party attempted to modify the page.
1495: *
1496: * Repeated asymmetric copy operations may be done.
1497: * If the original object has not been changed since
1498: * the last copy, its copy object can be reused.
1499: * Otherwise, a new copy object can be inserted
1500: * between the original object and its previous
1501: * copy object. Since any copy object is read-only,
1502: * this cannot affect the contents of the previous copy
1503: * object.
1504: *
1505: * Note that a copy object is higher in the object
1506: * tree than the original object; therefore, use of
1507: * the copy object recorded in the original object
1508: * must be done carefully, to avoid deadlock.
1509: */
1510:
1511: /*
1512: * Allocate a new copy object before locking, even
1513: * though we may not need it later.
1514: */
1515:
1516: new_copy = vm_object_allocate(src_object->size);
1517:
1518: vm_object_lock(src_object);
1519:
1520: /*
1521: * See whether we can reuse the result of a previous
1522: * copy operation.
1523: */
1524: Retry:
1525: old_copy = src_object->copy;
1526: if (old_copy != VM_OBJECT_NULL) {
1527: /*
1528: * Try to get the locks (out of order)
1529: */
1530: if (!vm_object_lock_try(old_copy)) {
1531: vm_object_unlock(src_object);
1532:
1533: simple_lock_pause(); /* wait a bit */
1534:
1535: vm_object_lock(src_object);
1536: goto Retry;
1537: }
1538:
1539: /*
1540: * Determine whether the old copy object has
1541: * been modified.
1542: */
1543:
1544: if (old_copy->resident_page_count == 0 &&
1545: !old_copy->pager_created) {
1546: /*
1547: * It has not been modified.
1548: *
1549: * Return another reference to
1550: * the existing copy-object.
1551: */
1552: assert(old_copy->ref_count > 0);
1553: old_copy->ref_count++;
1554: vm_object_unlock(old_copy);
1555: vm_object_unlock(src_object);
1556:
1557: vm_object_deallocate(new_copy);
1558:
1559: return old_copy;
1560: }
1561:
1562: /*
1563: * The copy-object is always made large enough to
1564: * completely shadow the original object, since
1565: * it may have several users who want to shadow
1566: * the original object at different points.
1567: */
1568:
1569: assert((old_copy->shadow == src_object) &&
1570: (old_copy->shadow_offset == (vm_offset_t) 0));
1571:
1572: /*
1573: * Make the old copy-object shadow the new one.
1574: * It will receive no more pages from the original
1575: * object.
1576: */
1577:
1578: src_object->ref_count--; /* remove ref. from old_copy */
1579: assert(src_object->ref_count > 0);
1580: old_copy->shadow = new_copy;
1581: assert(new_copy->ref_count > 0);
1582: new_copy->ref_count++;
1583: vm_object_unlock(old_copy); /* done with old_copy */
1584: }
1585:
1586: /*
1587: * Point the new copy at the existing object.
1588: */
1589:
1590: new_copy->shadow = src_object;
1591: new_copy->shadow_offset = 0;
1592: new_copy->shadowed = TRUE; /* caller must set needs_copy */
1593: assert(src_object->ref_count > 0);
1594: src_object->ref_count++;
1595: src_object->copy = new_copy;
1596:
1597: /*
1598: * Mark all pages of the existing object copy-on-write.
1599: * This object may have a shadow chain below it, but
1600: * those pages will already be marked copy-on-write.
1601: */
1602:
1603: queue_iterate(&src_object->memq, p, vm_page_t, listq) {
1604: if (!p->fictitious)
1605: pmap_page_protect(p->phys_addr,
1606: (VM_PROT_ALL & ~VM_PROT_WRITE &
1607: ~p->page_lock));
1608: }
1609:
1610: vm_object_unlock(src_object);
1611:
1612: return new_copy;
1613: }
1614:
1615: /*
1616: * Routine: vm_object_copy_strategically
1617: *
1618: * Purpose:
1619: * Perform a copy according to the source object's
1620: * declared strategy. This operation may block,
1621: * and may be interrupted.
1622: */
1623: kern_return_t vm_object_copy_strategically(
1624: register
1625: vm_object_t src_object,
1626: vm_offset_t src_offset,
1627: vm_size_t size,
1628: vm_object_t *dst_object, /* OUT */
1629: vm_offset_t *dst_offset, /* OUT */
1630: boolean_t *dst_needs_copy) /* OUT */
1631: {
1632: kern_return_t result = KERN_SUCCESS; /* to quiet gcc warnings */
1633: boolean_t interruptible = TRUE; /* XXX */
1634:
1635: assert(src_object != VM_OBJECT_NULL);
1636:
1637: vm_object_lock(src_object);
1638:
1639: /* XXX assert(!src_object->temporary); JSB FIXME */
1640:
1641: /*
1642: * The copy strategy is only valid if the memory manager
1643: * is "ready".
1644: */
1645:
1646: while (!src_object->pager_ready) {
1647: vm_object_wait( src_object,
1648: VM_OBJECT_EVENT_PAGER_READY,
1649: interruptible);
1650: if (interruptible &&
1651: (current_thread()->wait_result != THREAD_AWAKENED)) {
1652: *dst_object = VM_OBJECT_NULL;
1653: *dst_offset = 0;
1654: *dst_needs_copy = FALSE;
1655: return MACH_SEND_INTERRUPTED;
1656: }
1657: vm_object_lock(src_object);
1658: }
1659:
1660: /*
1661: * The object may be temporary (even though it is external).
1662: * If so, do a symmetric copy.
1663: */
1664:
1665: if (src_object->temporary) {
1666: /*
1667: * XXX
1668: * This does not count as intelligent!
1669: * This buys us the object->temporary optimizations,
1670: * but we aren't using a symmetric copy,
1671: * which may confuse the vm code. The correct thing
1672: * to do here is to figure out what to call to get
1673: * a temporary shadowing set up.
1674: */
1675: src_object->copy_strategy = MEMORY_OBJECT_COPY_DELAY;
1676: }
1677:
1678: /*
1679: * The object is permanent. Use the appropriate copy strategy.
1680: */
1681:
1682: switch (src_object->copy_strategy) {
1683: case MEMORY_OBJECT_COPY_NONE:
1684: if ((result = vm_object_copy_slowly(
1685: src_object,
1686: src_offset,
1687: size,
1688: interruptible,
1689: dst_object))
1690: == KERN_SUCCESS) {
1691: *dst_offset = 0;
1692: *dst_needs_copy = FALSE;
1693: }
1694: break;
1695:
1696: case MEMORY_OBJECT_COPY_CALL:
1697: if ((result = vm_object_copy_call(
1698: src_object,
1699: src_offset,
1700: size,
1701: dst_object))
1702: == KERN_SUCCESS) {
1703: *dst_offset = 0;
1704: *dst_needs_copy = FALSE;
1705: }
1706: break;
1707:
1708: case MEMORY_OBJECT_COPY_DELAY:
1709: vm_object_unlock(src_object);
1710: *dst_object = vm_object_copy_delayed(src_object);
1711: *dst_offset = src_offset;
1712: *dst_needs_copy = TRUE;
1713:
1714: result = KERN_SUCCESS;
1715: break;
1716: }
1717:
1718: return result;
1719: }
1720:
1721: /*
1722: * vm_object_shadow:
1723: *
1724: * Create a new object which is backed by the
1725: * specified existing object range. The source
1726: * object reference is deallocated.
1727: *
1728: * The new object and offset into that object
1729: * are returned in the source parameters.
1730: */
1731:
1732: void vm_object_shadow(
1733: vm_object_t *object, /* IN/OUT */
1734: vm_offset_t *offset, /* IN/OUT */
1735: vm_size_t length)
1736: {
1737: register vm_object_t source;
1738: register vm_object_t result;
1739:
1740: source = *object;
1741:
1742: /*
1743: * Allocate a new object with the given length
1744: */
1745:
1746: if ((result = vm_object_allocate(length)) == VM_OBJECT_NULL)
1747: panic("vm_object_shadow: no object for shadowing");
1748:
1749: /*
1750: * The new object shadows the source object, adding
1751: * a reference to it. Our caller changes his reference
1752: * to point to the new object, removing a reference to
1753: * the source object. Net result: no change of reference
1754: * count.
1755: */
1756: result->shadow = source;
1757:
1758: /*
1759: * Store the offset into the source object,
1760: * and fix up the offset into the new object.
1761: */
1762:
1763: result->shadow_offset = *offset;
1764:
1765: /*
1766: * Return the new things
1767: */
1768:
1769: *offset = 0;
1770: *object = result;
1771: }
1772:
1773: /*
1774: * The relationship between vm_object structures and
1775: * the memory_object ports requires careful synchronization.
1776: *
1777: * All associations are created by vm_object_enter. All three
1778: * port fields are filled in, as follows:
1779: * pager: the memory_object port itself, supplied by
1780: * the user requesting a mapping (or the kernel,
1781: * when initializing internal objects); the
1782: * kernel simulates holding send rights by keeping
1783: * a port reference;
1784: * pager_request:
1785: * pager_name:
1786: * the memory object control and name ports,
1787: * created by the kernel; the kernel holds
1788: * receive (and ownership) rights to these
1789: * ports, but no other references.
1790: * All of the ports are referenced by their global names.
1791: *
1792: * When initialization is complete, the "initialized" field
1793: * is asserted. Other mappings using a particular memory object,
1794: * and any references to the vm_object gained through the
1795: * port association must wait for this initialization to occur.
1796: *
1797: * In order to allow the memory manager to set attributes before
1798: * requests (notably virtual copy operations, but also data or
1799: * unlock requests) are made, a "ready" attribute is made available.
1800: * Only the memory manager may affect the value of this attribute.
1801: * Its value does not affect critical kernel functions, such as
1802: * internal object initialization or destruction. [Furthermore,
1803: * memory objects created by the kernel are assumed to be ready
1804: * immediately; the default memory manager need not explicitly
1805: * set the "ready" attribute.]
1806: *
1807: * [Both the "initialized" and "ready" attribute wait conditions
1808: * use the "pager" field as the wait event.]
1809: *
1810: * The port associations can be broken down by any of the
1811: * following routines:
1812: * vm_object_terminate:
1813: * No references to the vm_object remain, and
1814: * the object cannot (or will not) be cached.
1815: * This is the normal case, and is done even
1816: * though one of the other cases has already been
1817: * done.
1818: * vm_object_destroy:
1819: * The memory_object port has been destroyed,
1820: * meaning that the kernel cannot flush dirty
1821: * pages or request new data or unlock existing
1822: * data.
1823: * memory_object_destroy:
1824: * The memory manager has requested that the
1825: * kernel relinquish rights to the memory object
1826: * port. [The memory manager may not want to
1827: * destroy the port, but may wish to refuse or
1828: * tear down existing memory mappings.]
1829: * Each routine that breaks an association must break all of
1830: * them at once. At some later time, that routine must clear
1831: * the vm_object port fields and release the port rights.
1832: * [Furthermore, each routine must cope with the simultaneous
1833: * or previous operations of the others.]
1834: *
1835: * In addition to the lock on the object, the vm_object_cache_lock
1836: * governs the port associations. References gained through the
1837: * port association require use of the cache lock.
1838: *
1839: * Because the port fields may be cleared spontaneously, they
1840: * cannot be used to determine whether a memory object has
1841: * ever been associated with a particular vm_object. [This
1842: * knowledge is important to the shadow object mechanism.]
1843: * For this reason, an additional "created" attribute is
1844: * provided.
1845: *
1846: * During various paging operations, the port values found in the
1847: * vm_object must be valid. To prevent these port rights from being
1848: * released, and to prevent the port associations from changing
1849: * (other than being removed, i.e., made null), routines may use
1850: * the vm_object_paging_begin/end routines [actually, macros].
1851: * The implementation uses the "paging_in_progress" and "wanted" fields.
1852: * [Operations that alter the validity of the port values include the
1853: * termination routines and vm_object_collapse.]
1854: */
1855:
1856: vm_object_t vm_object_lookup(
1857: ipc_port_t port)
1858: {
1859: vm_object_t object = VM_OBJECT_NULL;
1860:
1861: if (IP_VALID(port)) {
1862: ip_lock(port);
1863: if (ip_active(port) &&
1864: #if NORMA_VM
1865: (ip_kotype(port) == IKOT_PAGER)) {
1866: #else /* NORMA_VM */
1867: (ip_kotype(port) == IKOT_PAGING_REQUEST)) {
1868: #endif /* NORMA_VM */
1869: vm_object_cache_lock();
1870: object = (vm_object_t) port->ip_kobject;
1871: vm_object_lock(object);
1872:
1873: assert(object->alive);
1874:
1875: if (object->ref_count == 0) {
1876: queue_remove(&vm_object_cached_list, object,
1877: vm_object_t, cached_list);
1878: vm_object_cached_count--;
1879: }
1880:
1881: object->ref_count++;
1882: vm_object_unlock(object);
1883: vm_object_cache_unlock();
1884: }
1885: ip_unlock(port);
1886: }
1887:
1888: return object;
1889: }
1890:
1891: vm_object_t vm_object_lookup_name(
1892: ipc_port_t port)
1893: {
1894: vm_object_t object = VM_OBJECT_NULL;
1895:
1896: if (IP_VALID(port)) {
1897: ip_lock(port);
1898: if (ip_active(port) &&
1899: (ip_kotype(port) == IKOT_PAGING_NAME)) {
1900: vm_object_cache_lock();
1901: object = (vm_object_t) port->ip_kobject;
1902: vm_object_lock(object);
1903:
1904: assert(object->alive);
1905:
1906: if (object->ref_count == 0) {
1907: queue_remove(&vm_object_cached_list, object,
1908: vm_object_t, cached_list);
1909: vm_object_cached_count--;
1910: }
1911:
1912: object->ref_count++;
1913: vm_object_unlock(object);
1914: vm_object_cache_unlock();
1915: }
1916: ip_unlock(port);
1917: }
1918:
1919: return object;
1920: }
1921:
1922: void vm_object_destroy(
1923: ipc_port_t pager)
1924: {
1925: vm_object_t object;
1926: pager_request_t old_request;
1927: ipc_port_t old_name;
1928:
1929: /*
1930: * Perform essentially the same operations as in vm_object_lookup,
1931: * except that this time we look up based on the memory_object
1932: * port, not the control port.
1933: */
1934: vm_object_cache_lock();
1935: if (ip_kotype(pager) != IKOT_PAGER) {
1936: vm_object_cache_unlock();
1937: return;
1938: }
1939:
1940: object = (vm_object_t) pager->ip_kobject;
1941: vm_object_lock(object);
1942: if (object->ref_count == 0) {
1943: queue_remove(&vm_object_cached_list, object,
1944: vm_object_t, cached_list);
1945: vm_object_cached_count--;
1946: }
1947: object->ref_count++;
1948:
1949: object->can_persist = FALSE;
1950:
1951: assert(object->pager == pager);
1952:
1953: /*
1954: * Remove the port associations.
1955: *
1956: * Note that the memory_object itself is dead, so
1957: * we don't bother with it.
1958: */
1959:
1960: object->pager = IP_NULL;
1961: vm_object_remove(object);
1962:
1963: old_request = object->pager_request;
1964: object->pager_request = PAGER_REQUEST_NULL;
1965:
1966: old_name = object->pager_name;
1967: object->pager_name = IP_NULL;
1968:
1969: vm_object_unlock(object);
1970: vm_object_cache_unlock();
1971:
1972: /*
1973: * Clean up the port references. Note that there's no
1974: * point in trying the memory_object_terminate call
1975: * because the memory_object itself is dead.
1976: */
1977:
1978: ipc_port_release_send(pager);
1979: #if !NORMA_VM
1980: if (old_request != IP_NULL)
1981: ipc_port_dealloc_kernel(old_request);
1982: #endif /* !NORMA_VM */
1983: if (old_name != IP_NULL)
1984: #if NORMA_VM
1985: ipc_port_release_send(old_name);
1986: #else /* NORMA_VM */
1987: ipc_port_dealloc_kernel(old_name);
1988: #endif /* NORMA_VM */
1989:
1990: /*
1991: * Restart pending page requests
1992: */
1993:
1994: vm_object_abort_activity(object);
1995:
1996: /*
1997: * Lose the object reference.
1998: */
1999:
2000: vm_object_deallocate(object);
2001: }
2002:
2003: boolean_t vm_object_accept_old_init_protocol = FALSE;
2004:
2005: /*
2006: * Routine: vm_object_enter
2007: * Purpose:
2008: * Find a VM object corresponding to the given
2009: * pager; if no such object exists, create one,
2010: * and initialize the pager.
2011: */
2012: vm_object_t vm_object_enter(
2013: ipc_port_t pager,
2014: vm_size_t size,
2015: boolean_t internal)
2016: {
2017: register
2018: vm_object_t object;
2019: vm_object_t new_object;
2020: boolean_t must_init;
2021: ipc_kobject_type_t po;
2022:
2023: restart:
2024: if (!IP_VALID(pager))
2025: return vm_object_allocate(size);
2026:
2027: new_object = VM_OBJECT_NULL;
2028: must_init = FALSE;
2029:
2030: /*
2031: * Look for an object associated with this port.
2032: */
2033:
2034: vm_object_cache_lock();
2035: for (;;) {
2036: po = ip_kotype(pager);
2037:
2038: /*
2039: * If a previous object is being terminated,
2040: * we must wait for the termination message
2041: * to be queued.
2042: *
2043: * We set kobject to a non-null value to let the
2044: * terminator know that someone is waiting.
2045: * Among the possibilities is that the port
2046: * could die while we're waiting. Must restart
2047: * instead of continuing the loop.
2048: */
2049:
2050: if (po == IKOT_PAGER_TERMINATING) {
2051: pager->ip_kobject = (ipc_kobject_t) pager;
2052: assert_wait((event_t) pager, FALSE);
2053: vm_object_cache_unlock();
2054: thread_block((void (*)()) 0);
2055: goto restart;
2056: }
2057:
2058: /*
2059: * Bail if there is already a kobject associated
2060: * with the pager port.
2061: */
2062: if (po != IKOT_NONE) {
2063: break;
2064: }
2065:
2066: /*
2067: * We must unlock to create a new object;
2068: * if we do so, we must try the lookup again.
2069: */
2070:
2071: if (new_object == VM_OBJECT_NULL) {
2072: vm_object_cache_unlock();
2073: new_object = vm_object_allocate(size);
2074: vm_object_cache_lock();
2075: } else {
2076: /*
2077: * Lookup failed twice, and we have something
2078: * to insert; set the object.
2079: */
2080:
2081: ipc_kobject_set(pager,
2082: (ipc_kobject_t) new_object,
2083: IKOT_PAGER);
2084: new_object = VM_OBJECT_NULL;
2085: must_init = TRUE;
2086: }
2087: }
2088:
2089: if (internal)
2090: must_init = TRUE;
2091:
2092: /*
2093: * It's only good if it's a VM object!
2094: */
2095:
2096: object = (po == IKOT_PAGER) ? (vm_object_t) pager->ip_kobject
2097: : VM_OBJECT_NULL;
2098:
2099: if ((object != VM_OBJECT_NULL) && !must_init) {
2100: vm_object_lock(object);
2101: if (object->ref_count == 0) {
2102: queue_remove(&vm_object_cached_list, object,
2103: vm_object_t, cached_list);
2104: vm_object_cached_count--;
2105: }
2106: object->ref_count++;
2107: vm_object_unlock(object);
2108:
2109: vm_stat.hits++;
2110: }
2111: assert((object == VM_OBJECT_NULL) || (object->ref_count > 0) ||
2112: ((object->paging_in_progress != 0) && internal));
2113:
2114: vm_stat.lookups++;
2115:
2116: vm_object_cache_unlock();
2117:
2118: /*
2119: * If we raced to create a vm_object but lost, let's
2120: * throw away ours.
2121: */
2122:
2123: if (new_object != VM_OBJECT_NULL)
2124: vm_object_deallocate(new_object);
2125:
2126: if (object == VM_OBJECT_NULL)
2127: return(object);
2128:
2129: if (must_init) {
2130: /*
2131: * Copy the naked send right we were given.
2132: */
2133:
2134: pager = ipc_port_copy_send(pager);
2135: if (!IP_VALID(pager))
2136: panic("vm_object_enter: port died"); /* XXX */
2137:
2138: object->pager_created = TRUE;
2139: object->pager = pager;
2140:
2141: #if NORMA_VM
2142:
2143: /*
2144: * Let the xmm system know that we want to use the pager.
2145: *
2146: * Name port will be provided by the xmm system
2147: * when set_attributes_common is called.
2148: */
2149:
2150: object->internal = internal;
2151: object->pager_ready = internal;
2152: if (internal) {
2153: assert(object->temporary);
2154: } else {
2155: object->temporary = FALSE;
2156: }
2157: object->pager_name = IP_NULL;
2158:
2159: (void) xmm_memory_object_init(object);
2160: #else /* NORMA_VM */
2161:
2162: /*
2163: * Allocate request port.
2164: */
2165:
2166: object->pager_request = ipc_port_alloc_kernel();
2167: if (object->pager_request == IP_NULL)
2168: panic("vm_object_enter: pager request alloc");
2169:
2170: ipc_kobject_set(object->pager_request,
2171: (ipc_kobject_t) object,
2172: IKOT_PAGING_REQUEST);
2173:
2174: /*
2175: * Let the pager know we're using it.
2176: */
2177:
2178: if (internal) {
2179: /* acquire a naked send right for the DMM */
2180: ipc_port_t DMM = memory_manager_default_reference();
2181:
2182: /* mark the object internal */
2183: object->internal = TRUE;
2184: assert(object->temporary);
2185:
2186: /* default-pager objects are ready immediately */
2187: object->pager_ready = TRUE;
2188:
2189: /* consumes the naked send right for DMM */
2190: (void) memory_object_create(DMM,
2191: pager,
2192: object->size,
2193: object->pager_request,
2194: object->pager_name,
2195: PAGE_SIZE);
2196: } else {
2197: /* the object is external and not temporary */
2198: object->internal = FALSE;
2199: object->temporary = FALSE;
2200:
2201: /* user pager objects are not ready until marked so */
2202: object->pager_ready = FALSE;
2203:
2204: (void) memory_object_init(pager,
2205: object->pager_request,
2206: object->pager_name,
2207: PAGE_SIZE);
2208:
2209: }
2210: #endif /* NORMA_VM */
2211:
2212: vm_object_lock(object);
2213: object->pager_initialized = TRUE;
2214:
2215: if (vm_object_accept_old_init_protocol)
2216: object->pager_ready = TRUE;
2217:
2218: vm_object_wakeup(object, VM_OBJECT_EVENT_INITIALIZED);
2219: } else {
2220: vm_object_lock(object);
2221: }
2222: /*
2223: * [At this point, the object must be locked]
2224: */
2225:
2226: /*
2227: * Wait for the work above to be done by the first
2228: * thread to map this object.
2229: */
2230:
2231: while (!object->pager_initialized) {
2232: vm_object_wait( object,
2233: VM_OBJECT_EVENT_INITIALIZED,
2234: FALSE);
2235: vm_object_lock(object);
2236: }
2237: vm_object_unlock(object);
2238:
2239: return object;
2240: }
2241:
2242: /*
2243: * Routine: vm_object_pager_create
2244: * Purpose:
2245: * Create a memory object for an internal object.
2246: * In/out conditions:
2247: * The object is locked on entry and exit;
2248: * it may be unlocked within this call.
2249: * Limitations:
2250: * Only one thread may be performing a
2251: * vm_object_pager_create on an object at
2252: * a time. Presumably, only the pageout
2253: * daemon will be using this routine.
2254: */
2255: void vm_object_pager_create(
2256: register
2257: vm_object_t object)
2258: {
2259: ipc_port_t pager;
2260:
2261: if (object->pager_created) {
2262: /*
2263: * Someone else got to it first...
2264: * wait for them to finish initializing
2265: */
2266:
2267: while (!object->pager_initialized) {
2268: vm_object_wait( object,
2269: VM_OBJECT_EVENT_PAGER_READY,
2270: FALSE);
2271: vm_object_lock(object);
2272: }
2273: return;
2274: }
2275:
2276: /*
2277: * Indicate that a memory object has been assigned
2278: * before dropping the lock, to prevent a race.
2279: */
2280:
2281: object->pager_created = TRUE;
2282:
2283: /*
2284: * Prevent collapse or termination by
2285: * holding a paging reference
2286: */
2287:
2288: vm_object_paging_begin(object);
2289: vm_object_unlock(object);
2290:
2291: #if MACH_PAGEMAP
2292: object->existence_info = vm_external_create(
2293: object->size +
2294: object->paging_offset);
2295: assert((object->size + object->paging_offset) >=
2296: object->size);
2297: #endif /* MACH_PAGEMAP */
2298:
2299: /*
2300: * Create the pager, and associate with it
2301: * this object.
2302: *
2303: * Note that we only make the port association
2304: * so that vm_object_enter can properly look up
2305: * the object to complete the initialization...
2306: * we do not expect any user to ever map this
2307: * object.
2308: *
2309: * Since the kernel has the only rights to the
2310: * port, it's safe to install the association
2311: * without holding the cache lock.
2312: */
2313:
2314: pager = ipc_port_alloc_kernel();
2315: if (pager == IP_NULL)
2316: panic("vm_object_pager_create: allocate pager port");
2317:
2318: (void) ipc_port_make_send(pager);
2319: ipc_kobject_set(pager, (ipc_kobject_t) object, IKOT_PAGER);
2320:
2321: /*
2322: * Initialize the rest of the paging stuff
2323: */
2324:
2325: if (vm_object_enter(pager, object->size, TRUE) != object)
2326: panic("vm_object_pager_create: mismatch");
2327:
2328: /*
2329: * Drop the naked send right taken above.
2330: */
2331:
2332: ipc_port_release_send(pager);
2333:
2334: /*
2335: * Release the paging reference
2336: */
2337:
2338: vm_object_lock(object);
2339: vm_object_paging_end(object);
2340: }
2341:
2342: /*
2343: * Routine: vm_object_remove
2344: * Purpose:
2345: * Eliminate the pager/object association
2346: * for this pager.
2347: * Conditions:
2348: * The object cache must be locked.
2349: */
2350: void vm_object_remove(
2351: vm_object_t object)
2352: {
2353: ipc_port_t port;
2354:
2355: if ((port = object->pager) != IP_NULL) {
2356: if (ip_kotype(port) == IKOT_PAGER)
2357: ipc_kobject_set(port, IKO_NULL,
2358: IKOT_PAGER_TERMINATING);
2359: else if (ip_kotype(port) != IKOT_NONE)
2360: panic("vm_object_remove: bad object port");
2361: }
2362: #if !NORMA_VM
2363: if ((port = object->pager_request) != IP_NULL) {
2364: if (ip_kotype(port) == IKOT_PAGING_REQUEST)
2365: ipc_kobject_set(port, IKO_NULL, IKOT_NONE);
2366: else if (ip_kotype(port) != IKOT_NONE)
2367: panic("vm_object_remove: bad request port");
2368: }
2369: if ((port = object->pager_name) != IP_NULL) {
2370: if (ip_kotype(port) == IKOT_PAGING_NAME)
2371: ipc_kobject_set(port, IKO_NULL, IKOT_NONE);
2372: else if (ip_kotype(port) != IKOT_NONE)
2373: panic("vm_object_remove: bad name port");
2374: }
2375: #endif /* !NORMA_VM */
2376: }
2377:
2378: /*
2379: * Global variables for vm_object_collapse():
2380: *
2381: * Counts for normal collapses and bypasses.
2382: * Debugging variables, to watch or disable collapse.
2383: */
2384: long object_collapses = 0;
2385: long object_bypasses = 0;
2386:
2387: int vm_object_collapse_debug = 0;
2388: boolean_t vm_object_collapse_allowed = TRUE;
2389: boolean_t vm_object_collapse_bypass_allowed = TRUE;
2390:
2391: /*
2392: * vm_object_collapse:
2393: *
2394: * Collapse an object with the object backing it.
2395: * Pages in the backing object are moved into the
2396: * parent, and the backing object is deallocated.
2397: *
2398: * Requires that the object be locked and the page
2399: * queues be unlocked. May unlock/relock the object,
2400: * so the caller should hold a reference for the object.
2401: */
2402: void vm_object_collapse(
2403: register vm_object_t object)
2404: {
2405: register vm_object_t backing_object;
2406: register vm_offset_t backing_offset;
2407: register vm_size_t size;
2408: register vm_offset_t new_offset;
2409: register vm_page_t p, pp;
2410: ipc_port_t old_name_port;
2411:
2412: if (!vm_object_collapse_allowed)
2413: return;
2414:
2415: while (TRUE) {
2416: /*
2417: * Verify that the conditions are right for collapse:
2418: *
2419: * The object exists and no pages in it are currently
2420: * being paged out (or have ever been paged out).
2421: *
2422: * This check is probably overkill -- if a memory
2423: * object has not been created, the fault handler
2424: * shouldn't release the object lock while paging
2425: * is in progress or absent pages exist.
2426: */
2427: if (object == VM_OBJECT_NULL ||
2428: object->pager_created ||
2429: object->paging_in_progress != 0 ||
2430: object->absent_count != 0)
2431: return;
2432:
2433: /*
2434: * There is a backing object, and
2435: */
2436:
2437: if ((backing_object = object->shadow) == VM_OBJECT_NULL)
2438: return;
2439:
2440: vm_object_lock(backing_object);
2441: /*
2442: * ...
2443: * The backing object is not read_only,
2444: * and no pages in the backing object are
2445: * currently being paged out.
2446: * The backing object is internal.
2447: *
2448: * XXX It may be sufficient for the backing
2449: * XXX object to be temporary.
2450: */
2451:
2452: if (!backing_object->internal ||
2453: backing_object->paging_in_progress != 0) {
2454: vm_object_unlock(backing_object);
2455: return;
2456: }
2457:
2458: /*
2459: * The backing object can't be a copy-object:
2460: * the shadow_offset for the copy-object must stay
2461: * as 0. Furthermore (for the 'we have all the
2462: * pages' case), if we bypass backing_object and
2463: * just shadow the next object in the chain, old
2464: * pages from that object would then have to be copied
2465: * BOTH into the (former) backing_object and into the
2466: * parent object.
2467: */
2468: if (backing_object->shadow != VM_OBJECT_NULL &&
2469: backing_object->shadow->copy != VM_OBJECT_NULL) {
2470: vm_object_unlock(backing_object);
2471: return;
2472: }
2473:
2474: /*
2475: * We know that we can either collapse the backing
2476: * object (if the parent is the only reference to
2477: * it) or (perhaps) remove the parent's reference
2478: * to it.
2479: */
2480:
2481: backing_offset = object->shadow_offset;
2482: size = object->size;
2483:
2484: /*
2485: * If there is exactly one reference to the backing
2486: * object, we can collapse it into the parent.
2487: */
2488:
2489: if (backing_object->ref_count == 1) {
2490: if (!vm_object_cache_lock_try()) {
2491: vm_object_unlock(backing_object);
2492: return;
2493: }
2494:
2495: /*
2496: * We can collapse the backing object.
2497: *
2498: * Move all in-memory pages from backing_object
2499: * to the parent. Pages that have been paged out
2500: * will be overwritten by any of the parent's
2501: * pages that shadow them.
2502: */
2503:
2504: while (!queue_empty(&backing_object->memq)) {
2505:
2506: p = (vm_page_t)
2507: queue_first(&backing_object->memq);
2508:
2509: new_offset = (p->offset - backing_offset);
2510:
2511: assert(!p->busy || p->absent);
2512:
2513: /*
2514: * If the parent has a page here, or if
2515: * this page falls outside the parent,
2516: * dispose of it.
2517: *
2518: * Otherwise, move it as planned.
2519: */
2520:
2521: if (p->offset < backing_offset ||
2522: new_offset >= size) {
2523: vm_page_lock_queues();
2524: vm_page_free(p);
2525: vm_page_unlock_queues();
2526: } else {
2527: pp = vm_page_lookup(object, new_offset);
2528: if (pp != VM_PAGE_NULL && !pp->absent) {
2529: /*
2530: * Parent object has a real page.
2531: * Throw away the backing object's
2532: * page.
2533: */
2534: vm_page_lock_queues();
2535: vm_page_free(p);
2536: vm_page_unlock_queues();
2537: }
2538: else {
2539: if (pp != VM_PAGE_NULL) {
2540: /*
2541: * Parent has an absent page...
2542: * it's not being paged in, so
2543: * it must really be missing from
2544: * the parent.
2545: *
2546: * Throw out the absent page...
2547: * any faults looking for that
2548: * page will restart with the new
2549: * one.
2550: */
2551:
2552: /*
2553: * This should never happen -- the
2554: * parent cannot have ever had an
2555: * external memory object, and thus
2556: * cannot have absent pages.
2557: */
2558: panic("vm_object_collapse: bad case");
2559:
2560: vm_page_lock_queues();
2561: vm_page_free(pp);
2562: vm_page_unlock_queues();
2563:
2564: /*
2565: * Fall through to move the backing
2566: * object's page up.
2567: */
2568: }
2569: /*
2570: * Parent now has no page.
2571: * Move the backing object's page up.
2572: */
2573: vm_page_rename(p, object, new_offset);
2574: }
2575: }
2576: }
2577:
2578: /*
2579: * Move the pager from backing_object to object.
2580: *
2581: * XXX We're only using part of the paging space
2582: * for keeps now... we ought to discard the
2583: * unused portion.
2584: */
2585:
2586: switch (vm_object_collapse_debug) {
2587: case 0:
2588: break;
2589: case 1:
2590: if ((backing_object->pager == IP_NULL) &&
2591: (backing_object->pager_request ==
2592: PAGER_REQUEST_NULL))
2593: break;
2594: /* Fall through to... */
2595:
2596: default:
2597: printf("vm_object_collapse: %#x (pager %#x, request %#x) up to %#x\n",
2598: backing_object, backing_object->pager, backing_object->pager_request,
2599: object);
2600: if (vm_object_collapse_debug > 2)
2601: Debugger("vm_object_collapse");
2602: }
2603:
2604: object->pager = backing_object->pager;
2605: if (object->pager != IP_NULL)
2606: ipc_kobject_set(object->pager,
2607: (ipc_kobject_t) object,
2608: IKOT_PAGER);
2609: object->pager_initialized = backing_object->pager_initialized;
2610: object->pager_ready = backing_object->pager_ready;
2611: object->pager_created = backing_object->pager_created;
2612:
2613: object->pager_request = backing_object->pager_request;
2614: #if NORMA_VM
2615: old_name_port = object->pager_name;
2616: object->pager_name = backing_object->pager_name;
2617: #else /* NORMA_VM */
2618: if (object->pager_request != IP_NULL)
2619: ipc_kobject_set(object->pager_request,
2620: (ipc_kobject_t) object,
2621: IKOT_PAGING_REQUEST);
2622: old_name_port = object->pager_name;
2623: if (old_name_port != IP_NULL)
2624: ipc_kobject_set(old_name_port,
2625: IKO_NULL, IKOT_NONE);
2626: object->pager_name = backing_object->pager_name;
2627: if (object->pager_name != IP_NULL)
2628: ipc_kobject_set(object->pager_name,
2629: (ipc_kobject_t) object,
2630: IKOT_PAGING_NAME);
2631: #endif /* NORMA_VM */
2632:
2633: vm_object_cache_unlock();
2634:
2635: /*
2636: * If there is no pager, leave paging-offset alone.
2637: */
2638: if (object->pager != IP_NULL)
2639: object->paging_offset =
2640: backing_object->paging_offset +
2641: backing_offset;
2642:
2643: #if MACH_PAGEMAP
2644: assert(object->existence_info == VM_EXTERNAL_NULL);
2645: object->existence_info = backing_object->existence_info;
2646: #endif /* MACH_PAGEMAP */
2647:
2648: /*
2649: * Object now shadows whatever backing_object did.
2650: * Note that the reference to backing_object->shadow
2651: * moves from within backing_object to within object.
2652: */
2653:
2654: object->shadow = backing_object->shadow;
2655: object->shadow_offset += backing_object->shadow_offset;
2656: if (object->shadow != VM_OBJECT_NULL &&
2657: object->shadow->copy != VM_OBJECT_NULL) {
2658: panic("vm_object_collapse: we collapsed a copy-object!");
2659: }
2660: /*
2661: * Discard backing_object.
2662: *
2663: * Since the backing object has no pages, no
2664: * pager left, and no object references within it,
2665: * all that is necessary is to dispose of it.
2666: */
2667:
2668: assert(
2669: (backing_object->ref_count == 1) &&
2670: (backing_object->resident_page_count == 0) &&
2671: (backing_object->paging_in_progress == 0)
2672: );
2673:
2674: assert(backing_object->alive);
2675: backing_object->alive = FALSE;
2676: vm_object_unlock(backing_object);
2677:
2678: vm_object_unlock(object);
2679: if (old_name_port != IP_NULL)
2680: #if NORMA_VM
2681: ipc_port_release_send(old_name_port);
2682: #else /* NORMA_VM */
2683: ipc_port_dealloc_kernel(old_name_port);
2684: #endif /* NORMA_VM */
2685: zfree(vm_object_zone, (vm_offset_t) backing_object);
2686: vm_object_lock(object);
2687:
2688: object_collapses++;
2689: }
2690: else {
2691: if (!vm_object_collapse_bypass_allowed) {
2692: vm_object_unlock(backing_object);
2693: return;
2694: }
2695:
2696: /*
2697: * If all of the pages in the backing object are
2698: * shadowed by the parent object, the parent
2699: * object no longer has to shadow the backing
2700: * object; it can shadow the next one in the
2701: * chain.
2702: *
2703: * The backing object must not be paged out - we'd
2704: * have to check all of the paged-out pages, as
2705: * well.
2706: */
2707:
2708: if (backing_object->pager_created) {
2709: vm_object_unlock(backing_object);
2710: return;
2711: }
2712:
2713: /*
2714: * Should have a check for a 'small' number
2715: * of pages here.
2716: */
2717:
2718: queue_iterate(&backing_object->memq, p,
2719: vm_page_t, listq)
2720: {
2721: new_offset = (p->offset - backing_offset);
2722:
2723: /*
2724: * If the parent has a page here, or if
2725: * this page falls outside the parent,
2726: * keep going.
2727: *
2728: * Otherwise, the backing_object must be
2729: * left in the chain.
2730: */
2731:
2732: if (p->offset >= backing_offset &&
2733: new_offset <= size &&
2734: (pp = vm_page_lookup(object, new_offset))
2735: == VM_PAGE_NULL) {
2736: /*
2737: * Page still needed.
2738: * Can't go any further.
2739: */
2740: vm_object_unlock(backing_object);
2741: return;
2742: }
2743: }
2744:
2745: /*
2746: * Make the parent shadow the next object
2747: * in the chain. Deallocating backing_object
2748: * will not remove it, since its reference
2749: * count is at least 2.
2750: */
2751:
2752: vm_object_reference(object->shadow = backing_object->shadow);
2753: object->shadow_offset += backing_object->shadow_offset;
2754:
2755: /*
2756: * Backing object might have had a copy pointer
2757: * to us. If it did, clear it.
2758: */
2759: if (backing_object->copy == object)
2760: backing_object->copy = VM_OBJECT_NULL;
2761:
2762: /*
2763: * Drop the reference count on backing_object.
2764: * Since its ref_count was at least 2, it
2765: * will not vanish; so we don't need to call
2766: * vm_object_deallocate.
2767: */
2768: backing_object->ref_count--;
2769: assert(backing_object->ref_count > 0);
2770: vm_object_unlock(backing_object);
2771:
2772: object_bypasses ++;
2773:
2774: }
2775:
2776: /*
2777: * Try again with this object's new backing object.
2778: */
2779: }
2780: }
2781:
2782: /*
2783: * Routine: vm_object_page_remove: [internal]
2784: * Purpose:
2785: * Removes all physical pages in the specified
2786: * object range from the object's list of pages.
2787: *
2788: * In/out conditions:
2789: * The object must be locked.
2790: */
2791: unsigned int vm_object_page_remove_lookup = 0;
2792: unsigned int vm_object_page_remove_iterate = 0;
2793:
2794: void vm_object_page_remove(
2795: register vm_object_t object,
2796: register vm_offset_t start,
2797: register vm_offset_t end)
2798: {
2799: register vm_page_t p, next;
2800:
2801: /*
2802: * One and two page removals are most popular.
2803: * The factor of 16 here is somewhat arbitrary.
2804: * It balances vm_object_lookup vs iteration.
2805: */
2806:
2807: if (atop(end - start) < (unsigned)object->resident_page_count/16) {
2808: vm_object_page_remove_lookup++;
2809:
2810: for (; start < end; start += PAGE_SIZE) {
2811: p = vm_page_lookup(object, start);
2812: if (p != VM_PAGE_NULL) {
2813: if (!p->fictitious)
2814: pmap_page_protect(p->phys_addr,
2815: VM_PROT_NONE);
2816: vm_page_lock_queues();
2817: vm_page_free(p);
2818: vm_page_unlock_queues();
2819: }
2820: }
2821: } else {
2822: vm_object_page_remove_iterate++;
2823:
2824: p = (vm_page_t) queue_first(&object->memq);
2825: while (!queue_end(&object->memq, (queue_entry_t) p)) {
2826: next = (vm_page_t) queue_next(&p->listq);
2827: if ((start <= p->offset) && (p->offset < end)) {
2828: if (!p->fictitious)
2829: pmap_page_protect(p->phys_addr,
2830: VM_PROT_NONE);
2831: vm_page_lock_queues();
2832: vm_page_free(p);
2833: vm_page_unlock_queues();
2834: }
2835: p = next;
2836: }
2837: }
2838: }
2839:
2840: /*
2841: * Routine: vm_object_coalesce
2842: * Function: Coalesces two objects backing up adjoining
2843: * regions of memory into a single object.
2844: *
2845: * returns TRUE if objects were combined.
2846: *
2847: * NOTE: Only works at the moment if the second object is NULL -
2848: * if it's not, which object do we lock first?
2849: *
2850: * Parameters:
2851: * prev_object First object to coalesce
2852: * prev_offset Offset into prev_object
2853: * next_object Second object into coalesce
2854: * next_offset Offset into next_object
2855: *
2856: * prev_size Size of reference to prev_object
2857: * next_size Size of reference to next_object
2858: *
2859: * Conditions:
2860: * The object must *not* be locked.
2861: */
2862:
2863: boolean_t vm_object_coalesce(
2864: register vm_object_t prev_object,
2865: vm_object_t next_object,
2866: vm_offset_t prev_offset,
2867: vm_offset_t next_offset,
2868: vm_size_t prev_size,
2869: vm_size_t next_size)
2870: {
2871: vm_size_t newsize;
2872:
2873: #ifdef lint
2874: next_offset++;
2875: #endif /* lint */
2876:
2877: if (next_object != VM_OBJECT_NULL) {
2878: return FALSE;
2879: }
2880:
2881: if (prev_object == VM_OBJECT_NULL) {
2882: return TRUE;
2883: }
2884:
2885: vm_object_lock(prev_object);
2886:
2887: /*
2888: * Try to collapse the object first
2889: */
2890: vm_object_collapse(prev_object);
2891:
2892: /*
2893: * Can't coalesce if pages not mapped to
2894: * prev_entry may be in use anyway:
2895: * . more than one reference
2896: * . paged out
2897: * . shadows another object
2898: * . has a copy elsewhere
2899: * . paging references (pages might be in page-list)
2900: */
2901:
2902: if ((prev_object->ref_count > 1) ||
2903: prev_object->pager_created ||
2904: (prev_object->shadow != VM_OBJECT_NULL) ||
2905: (prev_object->copy != VM_OBJECT_NULL) ||
2906: (prev_object->paging_in_progress != 0)) {
2907: vm_object_unlock(prev_object);
2908: return FALSE;
2909: }
2910:
2911: /*
2912: * Remove any pages that may still be in the object from
2913: * a previous deallocation.
2914: */
2915:
2916: vm_object_page_remove(prev_object,
2917: prev_offset + prev_size,
2918: prev_offset + prev_size + next_size);
2919:
2920: /*
2921: * Extend the object if necessary.
2922: */
2923: newsize = prev_offset + prev_size + next_size;
2924: if (newsize > prev_object->size)
2925: prev_object->size = newsize;
2926:
2927: vm_object_unlock(prev_object);
2928: return TRUE;
2929: }
2930:
2931: vm_object_t vm_object_request_object(
2932: ipc_port_t p)
2933: {
2934: return vm_object_lookup(p);
2935: }
2936:
2937: /*
2938: * Routine: vm_object_name
2939: * Purpose:
2940: * Returns a naked send right to the "name" port associated
2941: * with this object.
2942: */
2943: ipc_port_t vm_object_name(
2944: vm_object_t object)
2945: {
2946: ipc_port_t p;
2947:
2948: if (object == VM_OBJECT_NULL)
2949: return IP_NULL;
2950:
2951: vm_object_lock(object);
2952:
2953: while (object->shadow != VM_OBJECT_NULL) {
2954: vm_object_t new_object = object->shadow;
2955: vm_object_lock(new_object);
2956: vm_object_unlock(object);
2957: object = new_object;
2958: }
2959:
2960: p = object->pager_name;
2961: if (p != IP_NULL)
2962: #if NORMA_VM
2963: p = ipc_port_copy_send(p);
2964: #else /* NORMA_VM */
2965: p = ipc_port_make_send(p);
2966: #endif /* NORMA_VM */
2967: vm_object_unlock(object);
2968:
2969: return p;
2970: }
2971:
2972: /*
2973: * Attach a set of physical pages to an object, so that they can
2974: * be mapped by mapping the object. Typically used to map IO memory.
2975: *
2976: * The mapping function and its private data are used to obtain the
2977: * physical addresses for each page to be mapped.
2978: */
2979: void
2980: vm_object_page_map(
2981: vm_object_t object,
2982: vm_offset_t offset,
2983: vm_size_t size,
2984: vm_offset_t (*map_fn)(void *, vm_offset_t),
2985: void * map_fn_data) /* private to map_fn */
2986: {
2987: int num_pages;
2988: int i;
2989: vm_page_t m;
2990: vm_page_t old_page;
2991: vm_offset_t addr;
2992:
2993: num_pages = atop(size);
2994:
2995: for (i = 0; i < num_pages; i++, offset += PAGE_SIZE) {
2996:
2997: addr = (*map_fn)(map_fn_data, offset);
2998:
2999: while ((m = vm_page_grab_fictitious()) == VM_PAGE_NULL)
3000: vm_page_more_fictitious();
3001:
3002: vm_object_lock(object);
3003: if ((old_page = vm_page_lookup(object, offset))
3004: != VM_PAGE_NULL)
3005: {
3006: vm_page_lock_queues();
3007: vm_page_free(old_page);
3008: vm_page_unlock_queues();
3009: }
3010:
3011: vm_page_init(m, addr);
3012: m->private = TRUE; /* don`t free page */
3013: m->wire_count = 1;
3014: vm_page_lock_queues();
3015: vm_page_insert(m, object, offset);
3016: vm_page_unlock_queues();
3017:
3018: PAGE_WAKEUP_DONE(m);
3019: vm_object_unlock(object);
3020: }
3021: }
3022:
3023: #include <mach_kdb.h>
3024:
3025:
3026: #if MACH_KDB
3027: #define printf kdbprintf
3028:
3029: boolean_t vm_object_print_pages = FALSE;
3030:
3031: /*
3032: * vm_object_print: [ debug ]
3033: */
3034: void vm_object_print(
3035: vm_object_t object)
3036: {
3037: register vm_page_t p;
3038: extern indent;
3039:
3040: register int count;
3041:
3042: if (object == VM_OBJECT_NULL)
3043: return;
3044:
3045: iprintf("Object 0x%X: size=0x%X",
3046: (vm_offset_t) object, (vm_offset_t) object->size);
3047: printf(", %d references, %d resident pages,", object->ref_count,
3048: object->resident_page_count);
3049: printf(" %d absent pages,", object->absent_count);
3050: printf(" %d paging ops\n", object->paging_in_progress);
3051: indent += 2;
3052: iprintf("memory object=0x%X (offset=0x%X),",
3053: (vm_offset_t) object->pager, (vm_offset_t) object->paging_offset);
3054: printf("control=0x%X, name=0x%X\n",
3055: (vm_offset_t) object->pager_request, (vm_offset_t) object->pager_name);
3056: iprintf("%s%s",
3057: object->pager_ready ? " ready" : "",
3058: object->pager_created ? " created" : "");
3059: printf("%s,%s ",
3060: object->pager_initialized ? "" : "uninitialized",
3061: object->temporary ? "temporary" : "permanent");
3062: printf("%s%s,",
3063: object->internal ? "internal" : "external",
3064: object->can_persist ? " cacheable" : "");
3065: printf("copy_strategy=%d\n", (vm_offset_t)object->copy_strategy);
3066: iprintf("shadow=0x%X (offset=0x%X),",
3067: (vm_offset_t) object->shadow, (vm_offset_t) object->shadow_offset);
3068: printf("copy=0x%X\n", (vm_offset_t) object->copy);
3069:
3070: indent += 2;
3071:
3072: if (vm_object_print_pages) {
3073: count = 0;
3074: p = (vm_page_t) queue_first(&object->memq);
3075: while (!queue_end(&object->memq, (queue_entry_t) p)) {
3076: if (count == 0) iprintf("memory:=");
3077: else if (count == 4) {printf("\n"); iprintf(" ..."); count = 0;}
3078: else printf(",");
3079: count++;
3080:
3081: printf("(off=0x%X,page=0x%X)", p->offset, (vm_offset_t) p);
3082: p = (vm_page_t) queue_next(&p->listq);
3083: }
3084: if (count != 0)
3085: printf("\n");
3086: }
3087: indent -= 4;
3088: }
3089:
3090: #endif /* MACH_KDB */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.