Annotation of XNU/osfmk/vm/vm_object.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
                      3:  *
                      4:  * @APPLE_LICENSE_HEADER_START@
                      5:  * 
                      6:  * The contents of this file constitute Original Code as defined in and
                      7:  * are subject to the Apple Public Source License Version 1.1 (the
                      8:  * "License").  You may not use this file except in compliance with the
                      9:  * License.  Please obtain a copy of the License at
                     10:  * http://www.apple.com/publicsource and read it before using this file.
                     11:  * 
                     12:  * This Original Code and all software distributed under the License are
                     13:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
                     14:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
                     15:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
                     16:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
                     17:  * License for the specific language governing rights and limitations
                     18:  * under the License.
                     19:  * 
                     20:  * @APPLE_LICENSE_HEADER_END@
                     21:  */
                     22: /*
                     23:  * @OSF_COPYRIGHT@
                     24:  */
                     25: /* 
                     26:  * Mach Operating System
                     27:  * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University
                     28:  * All Rights Reserved.
                     29:  * 
                     30:  * Permission to use, copy, modify and distribute this software and its
                     31:  * documentation is hereby granted, provided that both the copyright
                     32:  * notice and this permission notice appear in all copies of the
                     33:  * software, derivative works or modified versions, and any portions
                     34:  * thereof, and that both notices appear in supporting documentation.
                     35:  * 
                     36:  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
                     37:  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
                     38:  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
                     39:  * 
                     40:  * Carnegie Mellon requests users of this software to return to
                     41:  * 
                     42:  *  Software Distribution Coordinator  or  [email protected]
                     43:  *  School of Computer Science
                     44:  *  Carnegie Mellon University
                     45:  *  Pittsburgh PA 15213-3890
                     46:  * 
                     47:  * any improvements or extensions that they make and grant Carnegie Mellon
                     48:  * the rights to redistribute these changes.
                     49:  */
                     50: /*
                     51:  */
                     52: /*
                     53:  *     File:   vm/vm_object.c
                     54:  *     Author: Avadis Tevanian, Jr., Michael Wayne Young
                     55:  *
                     56:  *     Virtual memory object module.
                     57:  */
                     58: 
                     59: #ifdef MACH_BSD
                     60: /* remove as part of compoenent support merge */
                     61: extern int     vnode_pager_workaround;
                     62: #endif
                     63: 
                     64: #include <mach_pagemap.h>
                     65: #include <task_swapper.h>
                     66: 
                     67: #include <mach/memory_object.h>
                     68: #include <mach/memory_object_default.h>
                     69: #include <mach/memory_object_control_server.h>
                     70: #include <mach/vm_param.h>
                     71: #include <ipc/ipc_port.h>
                     72: #include <ipc/ipc_space.h>
                     73: #include <kern/assert.h>
                     74: #include <kern/lock.h>
                     75: #include <kern/queue.h>
                     76: #include <kern/xpr.h>
                     77: #include <kern/zalloc.h>
                     78: #include <kern/host.h>
                     79: #include <kern/host_statistics.h>
                     80: #include <vm/memory_object.h>
                     81: #include <vm/vm_fault.h>
                     82: #include <vm/vm_map.h>
                     83: #include <vm/vm_object.h>
                     84: #include <vm/vm_page.h>
                     85: #include <vm/vm_pageout.h>
                     86: #include <kern/misc_protos.h>
                     87: 
                     88: /*
                     89:  *     Virtual memory objects maintain the actual data
                     90:  *     associated with allocated virtual memory.  A given
                     91:  *     page of memory exists within exactly one object.
                     92:  *
                     93:  *     An object is only deallocated when all "references"
                     94:  *     are given up.  Only one "reference" to a given
                     95:  *     region of an object should be writeable.
                     96:  *
                     97:  *     Associated with each object is a list of all resident
                     98:  *     memory pages belonging to that object; this list is
                     99:  *     maintained by the "vm_page" module, but locked by the object's
                    100:  *     lock.
                    101:  *
                    102:  *     Each object also records the memory object port
                    103:  *     that is used by the kernel to request and write
                    104:  *     back data (the memory object port, field "pager"),
                    105:  *     and the ports provided to the memory manager, the server that
                    106:  *     manages that data, to return data and control its
                    107:  *     use (the memory object control port, field "pager_request")
                    108:  *     and for naming (the memory object name port, field "pager_name").
                    109:  *
                    110:  *     Virtual memory objects are allocated to provide
                    111:  *     zero-filled memory (vm_allocate) or map a user-defined
                    112:  *     memory object into a virtual address space (vm_map).
                    113:  *
                    114:  *     Virtual memory objects that refer to a user-defined
                    115:  *     memory object are called "permanent", because all changes
                    116:  *     made in virtual memory are reflected back to the
                    117:  *     memory manager, which may then store it permanently.
                    118:  *     Other virtual memory objects are called "temporary",
                    119:  *     meaning that changes need be written back only when
                    120:  *     necessary to reclaim pages, and that storage associated
                    121:  *     with the object can be discarded once it is no longer
                    122:  *     mapped.
                    123:  *
                    124:  *     A permanent memory object may be mapped into more
                    125:  *     than one virtual address space.  Moreover, two threads
                    126:  *     may attempt to make the first mapping of a memory
                    127:  *     object concurrently.  Only one thread is allowed to
                    128:  *     complete this mapping; all others wait for the
                    129:  *     "pager_initialized" field is asserted, indicating
                    130:  *     that the first thread has initialized all of the
                    131:  *     necessary fields in the virtual memory object structure.
                    132:  *
                    133:  *     The kernel relies on a *default memory manager* to
                    134:  *     provide backing storage for the zero-filled virtual
                    135:  *     memory objects.  The memory object ports associated
                    136:  *     with these temporary virtual memory objects are only
                    137:  *     generated and passed to the default memory manager
                    138:  *     when it becomes necessary.  Virtual memory objects
                    139:  *     that depend on the default memory manager are called
                    140:  *     "internal".  The "pager_created" field is provided to
                    141:  *     indicate whether these ports have ever been allocated.
                    142:  *     
                    143:  *     The kernel may also create virtual memory objects to
                    144:  *     hold changed pages after a copy-on-write operation.
                    145:  *     In this case, the virtual memory object (and its
                    146:  *     backing storage -- its memory object) only contain
                    147:  *     those pages that have been changed.  The "shadow"
                    148:  *     field refers to the virtual memory object that contains
                    149:  *     the remainder of the contents.  The "shadow_offset"
                    150:  *     field indicates where in the "shadow" these contents begin.
                    151:  *     The "copy" field refers to a virtual memory object
                    152:  *     to which changed pages must be copied before changing
                    153:  *     this object, in order to implement another form
                    154:  *     of copy-on-write optimization.
                    155:  *
                    156:  *     The virtual memory object structure also records
                    157:  *     the attributes associated with its memory object.
                    158:  *     The "pager_ready", "can_persist" and "copy_strategy"
                    159:  *     fields represent those attributes.  The "cached_list"
                    160:  *     field is used in the implementation of the persistence
                    161:  *     attribute.
                    162:  *
                    163:  * ZZZ Continue this comment.
                    164:  */
                    165: 
                    166: /* Forward declarations for internal functions. */
                    167: extern void            _vm_object_allocate(
                    168:                                vm_size_t       size,
                    169:                                vm_object_t     object);
                    170: 
                    171: extern void            vm_object_terminate(
                    172:                                vm_object_t     object);
                    173: 
                    174: extern void            vm_object_remove(
                    175:                                vm_object_t     object);
                    176: 
                    177: extern vm_object_t     vm_object_cache_trim(
                    178:                                boolean_t called_from_vm_object_deallocate);
                    179: 
                    180: extern void            vm_object_deactivate_pages(
                    181:                                vm_object_t     object);
                    182: 
                    183: extern void            vm_object_abort_activity(
                    184:                                vm_object_t     object);
                    185: 
                    186: extern kern_return_t   vm_object_copy_call(
                    187:                                vm_object_t     src_object,
                    188:                                vm_offset_t     src_offset,
                    189:                                vm_size_t       size,
                    190:                                vm_object_t     *_result_object);
                    191: 
                    192: extern void            vm_object_do_collapse(
                    193:                                vm_object_t     object,
                    194:                                vm_object_t     backing_object);
                    195: 
                    196: extern void            vm_object_do_bypass(
                    197:                                vm_object_t     object,
                    198:                                vm_object_t     backing_object);
                    199: 
                    200: extern void            memory_object_release(
                    201:                                ipc_port_t      pager,
                    202:                                pager_request_t pager_request);
                    203: 
                    204: zone_t         vm_object_zone;         /* vm backing store zone */
                    205: 
                    206: /*
                    207:  *     All wired-down kernel memory belongs to a single virtual
                    208:  *     memory object (kernel_object) to avoid wasting data structures.
                    209:  */
                    210: struct vm_object       kernel_object_store;
                    211: vm_object_t            kernel_object = &kernel_object_store;
                    212: 
                    213: /*
                    214:  *     The submap object is used as a placeholder for vm_map_submap
                    215:  *     operations.  The object is declared in vm_map.c because it
                    216:  *     is exported by the vm_map module.  The storage is declared
                    217:  *     here because it must be initialized here.
                    218:  */
                    219: struct vm_object       vm_submap_object_store;
                    220: 
                    221: /*
                    222:  *     Virtual memory objects are initialized from
                    223:  *     a template (see vm_object_allocate).
                    224:  *
                    225:  *     When adding a new field to the virtual memory
                    226:  *     object structure, be sure to add initialization
                    227:  *     (see vm_object_init).
                    228:  */
                    229: struct vm_object       vm_object_template;
                    230: 
                    231: /*
                    232:  *     Virtual memory objects that are not referenced by
                    233:  *     any address maps, but that are allowed to persist
                    234:  *     (an attribute specified by the associated memory manager),
                    235:  *     are kept in a queue (vm_object_cached_list).
                    236:  *
                    237:  *     When an object from this queue is referenced again,
                    238:  *     for example to make another address space mapping,
                    239:  *     it must be removed from the queue.  That is, the
                    240:  *     queue contains *only* objects with zero references.
                    241:  *
                    242:  *     The kernel may choose to terminate objects from this
                    243:  *     queue in order to reclaim storage.  The current policy
                    244:  *     is to permit a fixed maximum number of unreferenced
                    245:  *     objects (vm_object_cached_max).
                    246:  *
                    247:  *     A spin lock (accessed by routines
                    248:  *     vm_object_cache_{lock,lock_try,unlock}) governs the
                    249:  *     object cache.  It must be held when objects are
                    250:  *     added to or removed from the cache (in vm_object_terminate).
                    251:  *     The routines that acquire a reference to a virtual
                    252:  *     memory object based on one of the memory object ports
                    253:  *     must also lock the cache.
                    254:  *
                    255:  *     Ideally, the object cache should be more isolated
                    256:  *     from the reference mechanism, so that the lock need
                    257:  *     not be held to make simple references.
                    258:  */
                    259: queue_head_t   vm_object_cached_list;
                    260: int            vm_object_cached_count;
                    261: int            vm_object_cached_high;  /* highest # of cached objects */
                    262: int            vm_object_cached_max = 500;     /* may be patched*/
                    263: 
                    264: decl_mutex_data(,vm_object_cached_lock_data)
                    265: 
                    266: #define vm_object_cache_lock()         \
                    267:                mutex_lock(&vm_object_cached_lock_data)
                    268: #define vm_object_cache_lock_try()     \
                    269:                mutex_try(&vm_object_cached_lock_data)
                    270: #define vm_object_cache_unlock()       \
                    271:                mutex_unlock(&vm_object_cached_lock_data)
                    272: 
                    273: #define        VM_OBJECT_HASH_COUNT            1024
                    274: queue_head_t   vm_object_hashtable[VM_OBJECT_HASH_COUNT];
                    275: struct zone    *vm_object_hash_zone;
                    276: 
                    277: struct vm_object_hash_entry {
                    278:        queue_chain_t           hash_link;      /* hash chain link */
                    279:        ipc_port_t              pager;          /* pager we represent */
                    280:        vm_object_t             object;         /* corresponding object */
                    281:        boolean_t               waiting;        /* someone waiting for
                    282:                                                 * termination */
                    283: };
                    284: 
                    285: typedef struct vm_object_hash_entry    *vm_object_hash_entry_t;
                    286: #define VM_OBJECT_HASH_ENTRY_NULL      ((vm_object_hash_entry_t) 0)
                    287: 
                    288: #define VM_OBJECT_HASH_SHIFT   8
                    289: #define vm_object_hash(pager) \
                    290:        ((((unsigned)pager) >> VM_OBJECT_HASH_SHIFT) % VM_OBJECT_HASH_COUNT)
                    291: 
                    292: /*
                    293:  *     vm_object_hash_lookup looks up a pager in the hashtable
                    294:  *     and returns the corresponding entry, with optional removal.
                    295:  */
                    296: 
                    297: vm_object_hash_entry_t
                    298: vm_object_hash_lookup(
                    299:        ipc_port_t      pager,
                    300:        boolean_t       remove_entry)
                    301: {
                    302:        register queue_t                bucket;
                    303:        register vm_object_hash_entry_t entry;
                    304: 
                    305:        bucket = &vm_object_hashtable[vm_object_hash(pager)];
                    306: 
                    307:        entry = (vm_object_hash_entry_t)queue_first(bucket);
                    308:        while (!queue_end(bucket, (queue_entry_t)entry)) {
                    309:                if (entry->pager == pager && !remove_entry)
                    310:                        return(entry);
                    311:                else if (entry->pager == pager) {
                    312:                        queue_remove(bucket, entry,
                    313:                                        vm_object_hash_entry_t, hash_link);
                    314:                        return(entry);
                    315:                }
                    316: 
                    317:                entry = (vm_object_hash_entry_t)queue_next(&entry->hash_link);
                    318:        }
                    319: 
                    320:        return(VM_OBJECT_HASH_ENTRY_NULL);
                    321: }
                    322: 
                    323: /*
                    324:  *     vm_object_hash_enter enters the specified
                    325:  *     pager / cache object association in the hashtable.
                    326:  */
                    327: 
                    328: void
                    329: vm_object_hash_insert(
                    330:        vm_object_hash_entry_t  entry)
                    331: {
                    332:        register queue_t                bucket;
                    333: 
                    334:        bucket = &vm_object_hashtable[vm_object_hash(entry->pager)];
                    335: 
                    336:        queue_enter(bucket, entry, vm_object_hash_entry_t, hash_link);
                    337: }
                    338: 
                    339: vm_object_hash_entry_t
                    340: vm_object_hash_entry_alloc(
                    341:        ipc_port_t      pager)
                    342: {
                    343:        vm_object_hash_entry_t  entry;
                    344: 
                    345:        entry = (vm_object_hash_entry_t)zalloc(vm_object_hash_zone);
                    346:        entry->pager = pager;
                    347:        entry->object = VM_OBJECT_NULL;
                    348:        entry->waiting = FALSE;
                    349: 
                    350:        return(entry);
                    351: }
                    352: 
                    353: void
                    354: vm_object_hash_entry_free(
                    355:        vm_object_hash_entry_t  entry)
                    356: {
                    357:        zfree(vm_object_hash_zone, (vm_offset_t)entry);
                    358: }
                    359: 
                    360: /*
                    361:  *     vm_object_allocate:
                    362:  *
                    363:  *     Returns a new object with the given size.
                    364:  */
                    365: 
                    366: void
                    367: _vm_object_allocate(
                    368:        vm_size_t       size,
                    369:        vm_object_t     object)
                    370: {
                    371:        XPR(XPR_VM_OBJECT,
                    372:                "vm_object_allocate, object 0x%X size 0x%X\n",
                    373:                (integer_t)object, size, 0,0,0);
                    374: 
                    375:        *object = vm_object_template;
                    376:        queue_init(&object->memq);
                    377:        queue_init(&object->msr_q);
                    378:        vm_object_lock_init(object);
                    379:        object->size = size;
                    380: }
                    381: 
                    382: vm_object_t
                    383: vm_object_allocate(
                    384:        vm_size_t       size)
                    385: {
                    386:        register vm_object_t object;
                    387:        register ipc_port_t port;
                    388: 
                    389:        object = (vm_object_t) zalloc(vm_object_zone);
                    390:        
                    391: //     dbgLog(object, size, 0, 2);                                             /* (TEST/DEBUG) */
                    392:        
                    393:        _vm_object_allocate(size, object);
                    394: 
                    395:        return object;
                    396: }
                    397: 
                    398: /*
                    399:  *     vm_object_bootstrap:
                    400:  *
                    401:  *     Initialize the VM objects module.
                    402:  */
                    403: void
                    404: vm_object_bootstrap(void)
                    405: {
                    406:        register        i;
                    407: 
                    408:        vm_object_zone = zinit((vm_size_t) sizeof(struct vm_object),
                    409:                                round_page(512*1024),
                    410:                                round_page(12*1024),
                    411:                                "vm objects");
                    412: 
                    413:        queue_init(&vm_object_cached_list);
                    414:        mutex_init(&vm_object_cached_lock_data, ETAP_VM_OBJ_CACHE);
                    415: 
                    416:        vm_object_hash_zone =
                    417:                        zinit((vm_size_t) sizeof (struct vm_object_hash_entry),
                    418:                              round_page(512*1024),
                    419:                              round_page(12*1024),
                    420:                              "vm object hash entries");
                    421: 
                    422:        for (i = 0; i < VM_OBJECT_HASH_COUNT; i++)
                    423:                queue_init(&vm_object_hashtable[i]);
                    424: 
                    425:        /*
                    426:         *      Fill in a template object, for quick initialization
                    427:         */
                    428: 
                    429:        /* memq; Lock; init after allocation */
                    430:        vm_object_template.size = 0;
                    431:        vm_object_template.frozen_size = 0;
                    432:        vm_object_template.ref_count = 1;
                    433: #if    TASK_SWAPPER
                    434:        vm_object_template.res_count = 1;
                    435: #endif /* TASK_SWAPPER */
                    436:        vm_object_template.resident_page_count = 0;
                    437:        vm_object_template.copy = VM_OBJECT_NULL;
                    438:        vm_object_template.shadow = VM_OBJECT_NULL;
                    439:        vm_object_template.shadow_offset = (vm_offset_t) 0;
                    440:        vm_object_template.true_share = FALSE;
                    441: 
                    442:        vm_object_template.pager = IP_NULL;
                    443:        vm_object_template.paging_offset = 0;
                    444:        vm_object_template.pager_request = PAGER_REQUEST_NULL;
                    445:        /* msr_q; init after allocation */
                    446: 
                    447:        vm_object_template.copy_strategy = MEMORY_OBJECT_COPY_SYMMETRIC;
                    448:        vm_object_template.absent_count = 0;
                    449:        vm_object_template.paging_in_progress = 0;
                    450: 
                    451:        /* Begin bitfields */
                    452:        vm_object_template.all_wanted = 0; /* all bits FALSE */
                    453:        vm_object_template.pager_created = FALSE;
                    454:        vm_object_template.pager_initialized = FALSE;
                    455:        vm_object_template.pager_ready = FALSE;
                    456:        vm_object_template.pager_trusted = FALSE;
                    457:        vm_object_template.can_persist = FALSE;
                    458:        vm_object_template.internal = TRUE;
                    459:        vm_object_template.temporary = TRUE;
                    460:        vm_object_template.private = FALSE;
                    461:        vm_object_template.pageout = FALSE;
                    462:        vm_object_template.alive = TRUE;
                    463:        vm_object_template.lock_in_progress = FALSE;
                    464:        vm_object_template.lock_restart = FALSE;
                    465:        vm_object_template.silent_overwrite = FALSE;
                    466:        vm_object_template.advisory_pageout = FALSE;
                    467:        vm_object_template.shadowed = FALSE;
                    468:        /* End bitfields */
                    469: 
                    470:        /* cached_list; init after allocation */
                    471:        vm_object_template.last_alloc = (vm_offset_t) 0;
                    472:        vm_object_template.cluster_size = 0;
                    473: #if    MACH_PAGEMAP
                    474:        vm_object_template.existence_map = VM_EXTERNAL_NULL;
                    475: #endif /* MACH_PAGEMAP */
                    476: #if    MACH_ASSERT
                    477:        vm_object_template.paging_object = VM_OBJECT_NULL;
                    478: #endif /* MACH_ASSERT */
                    479: 
                    480:        /*
                    481:         *      Initialize the "kernel object"
                    482:         */
                    483: 
                    484:        kernel_object = &kernel_object_store;
                    485: 
                    486: /*
                    487:  *     Note that in the following size specifications, we need to add 1 because 
                    488:  *     VM_MAX_KERNEL_ADDRESS is a maximum address, not a size.
                    489:  */
                    490:        _vm_object_allocate((VM_MAX_KERNEL_ADDRESS - VM_MIN_KERNEL_ADDRESS) + 1,
                    491:                        kernel_object);
                    492: 
                    493:        /*
                    494:         *      Initialize the "submap object".  Make it as large as the
                    495:         *      kernel object so that no limit is imposed on submap sizes.
                    496:         */
                    497: 
                    498:        vm_submap_object = &vm_submap_object_store;
                    499:        _vm_object_allocate((VM_MAX_KERNEL_ADDRESS - VM_MIN_KERNEL_ADDRESS) + 1,
                    500:                        vm_submap_object);
                    501:        /*
                    502:         * Create an "extra" reference to this object so that we never
                    503:         * try to deallocate it; zfree doesn't like to be called with
                    504:         * non-zone memory.
                    505:         */
                    506:        vm_object_reference(vm_submap_object);
                    507: 
                    508: #if    MACH_PAGEMAP
                    509:        vm_external_module_initialize();
                    510: #endif /* MACH_PAGEMAP */
                    511: }
                    512: 
                    513: void
                    514: vm_object_init(void)
                    515: {
                    516:        /*
                    517:         *      Finish initializing the kernel object.
                    518:         */
                    519: }
                    520: 
                    521: #if    TASK_SWAPPER
                    522: /*
                    523:  * vm_object_res_deallocate
                    524:  *
                    525:  * (recursively) decrement residence counts on vm objects and their shadows.
                    526:  * Called from vm_object_deallocate and when swapping out an object.
                    527:  *
                    528:  * The object is locked, and remains locked throughout the function,
                    529:  * even as we iterate down the shadow chain.  Locks on intermediate objects
                    530:  * will be dropped, but not the original object.
                    531:  *
                    532:  * NOTE: this function used to use recursion, rather than iteration.
                    533:  */
                    534: 
                    535: void
                    536: vm_object_res_deallocate(
                    537:        vm_object_t     object)
                    538: {
                    539:        vm_object_t orig_object = object;
                    540:        /*
                    541:         * Object is locked so it can be called directly
                    542:         * from vm_object_deallocate.  Original object is never
                    543:         * unlocked.
                    544:         */
                    545:        assert(object->res_count > 0);
                    546:        while  (--object->res_count == 0) {
                    547:                assert(object->ref_count >= object->res_count);
                    548:                vm_object_deactivate_pages(object);
                    549:                /* iterate on shadow, if present */
                    550:                if (object->shadow != VM_OBJECT_NULL) {
                    551:                        vm_object_t tmp_object = object->shadow;
                    552:                        vm_object_lock(tmp_object);
                    553:                        if (object != orig_object)
                    554:                                vm_object_unlock(object);
                    555:                        object = tmp_object;
                    556:                        assert(object->res_count > 0);
                    557:                } else
                    558:                        break;
                    559:        }
                    560:        if (object != orig_object)
                    561:                vm_object_unlock(object);
                    562: }
                    563: 
                    564: /*
                    565:  * vm_object_res_reference
                    566:  *
                    567:  * Internal function to increment residence count on a vm object
                    568:  * and its shadows.  It is called only from vm_object_reference, and
                    569:  * when swapping in a vm object, via vm_map_swap.
                    570:  *
                    571:  * The object is locked, and remains locked throughout the function,
                    572:  * even as we iterate down the shadow chain.  Locks on intermediate objects
                    573:  * will be dropped, but not the original object.
                    574:  *
                    575:  * NOTE: this function used to use recursion, rather than iteration.
                    576:  */
                    577: 
                    578: void
                    579: vm_object_res_reference(
                    580:        vm_object_t     object)
                    581: {
                    582:        vm_object_t orig_object = object;
                    583:        /* 
                    584:         * Object is locked, so this can be called directly
                    585:         * from vm_object_reference.  This lock is never released.
                    586:         */
                    587:        while  ((++object->res_count == 1)  && 
                    588:                (object->shadow != VM_OBJECT_NULL)) {
                    589:                vm_object_t tmp_object = object->shadow;
                    590: 
                    591:                assert(object->ref_count >= object->res_count);
                    592:                vm_object_lock(tmp_object);
                    593:                if (object != orig_object)
                    594:                        vm_object_unlock(object);
                    595:                object = tmp_object;
                    596:        }
                    597:        if (object != orig_object)
                    598:                vm_object_unlock(object);
                    599:        assert(orig_object->ref_count >= orig_object->res_count);
                    600: }
                    601: #endif /* TASK_SWAPPER */
                    602: 
                    603: #if    MACH_ASSERT
                    604: /*
                    605:  *     vm_object_reference:
                    606:  *
                    607:  *     Gets another reference to the given object.
                    608:  */
                    609: void
                    610: vm_object_reference(
                    611:        register vm_object_t    object)
                    612: {
                    613:        if (object == VM_OBJECT_NULL)
                    614:                return;
                    615: 
                    616:        vm_object_lock(object);
                    617:        assert(object->ref_count > 0);
                    618:        object->ref_count++;
                    619:        vm_object_res_reference(object);
                    620:        vm_object_unlock(object);
                    621: }
                    622: #endif /* MACH_ASSERT */
                    623: 
                    624: #define        MIGHT_NOT_CACHE_SHADOWS         1
                    625: #if    MIGHT_NOT_CACHE_SHADOWS
                    626: int cache_shadows = TRUE;
                    627: #endif /* MIGHT_NOT_CACHE_SHADOWS */
                    628: 
                    629: /*
                    630:  *     vm_object_deallocate:
                    631:  *
                    632:  *     Release a reference to the specified object,
                    633:  *     gained either through a vm_object_allocate
                    634:  *     or a vm_object_reference call.  When all references
                    635:  *     are gone, storage associated with this object
                    636:  *     may be relinquished.
                    637:  *
                    638:  *     No object may be locked.
                    639:  */
                    640: void
                    641: vm_object_deallocate(
                    642:        register vm_object_t    object)
                    643: {
                    644:        boolean_t retry_cache_trim = FALSE;
                    645:        vm_object_t shadow;
                    646:        
                    647: //     if(object)dbgLog(object, object->ref_count, object->can_persist, 3);    /* (TEST/DEBUG) */
                    648: //     else dbgLog(object, 0, 0, 3);   /* (TEST/DEBUG) */
                    649: 
                    650: 
                    651:        while (object != VM_OBJECT_NULL) {
                    652: 
                    653:                /*
                    654:                 *      The cache holds a reference (uncounted) to
                    655:                 *      the object; we must lock it before removing
                    656:                 *      the object.
                    657:                 */
                    658: 
                    659:                vm_object_cache_lock();
                    660:                vm_object_lock(object);
                    661:                assert(object->alive);
                    662: 
                    663:                /*
                    664:                 *      Lose the reference. If other references
                    665:                 *      remain, then we are done, unless we need
                    666:                 *      to retry a cache trim.
                    667:                 *      If it is the last reference, then keep it
                    668:                 *      until any pending initialization is completed.
                    669:                 */
                    670: 
                    671:                assert(object->ref_count > 0);
                    672:                if (object->ref_count > 1) {
                    673:                        object->ref_count--;
                    674:                        vm_object_res_deallocate(object);
                    675:                        vm_object_unlock(object);
                    676:                        vm_object_cache_unlock();
                    677:                        if (retry_cache_trim &&
                    678:                            ((object = vm_object_cache_trim(TRUE)) !=
                    679:                             VM_OBJECT_NULL)) {
                    680:                                continue;
                    681:                        }
                    682:                        return;
                    683:                }
                    684: 
                    685:                /*
                    686:                 *      We have to wait for initialization
                    687:                 *      before destroying or caching the object.
                    688:                 */
                    689:                
                    690:                if (object->pager_created && ! object->pager_initialized) {
                    691:                        assert(! object->can_persist);
                    692:                        vm_object_assert_wait(object,
                    693:                                              VM_OBJECT_EVENT_INITIALIZED,
                    694:                                              THREAD_UNINT);
                    695:                        vm_object_unlock(object);
                    696:                        vm_object_cache_unlock();
                    697:                        thread_block((void (*)(void))0);
                    698:                        continue;
                    699:                }
                    700: 
                    701:                /*
                    702:                 *      If this object can persist, then enter it in
                    703:                 *      the cache. Otherwise, terminate it.
                    704:                 *
                    705:                 *      NOTE:  Only permanent objects are cached, and
                    706:                 *      permanent objects cannot have shadows.  This
                    707:                 *      affects the residence counting logic in a minor
                    708:                 *      way (can do it in-line, mostly).
                    709:                 */
                    710: 
                    711:                if (object->can_persist) {
                    712:                        /*
                    713:                         *      Now it is safe to decrement reference count,
                    714:                         *      and to return if reference count is > 0.
                    715:                         */
                    716:                        if (--object->ref_count > 0) {
                    717:                                vm_object_res_deallocate(object);
                    718:                                vm_object_unlock(object);
                    719:                                vm_object_cache_unlock();
                    720:                                if (retry_cache_trim &&
                    721:                                    ((object = vm_object_cache_trim(TRUE)) !=
                    722:                                     VM_OBJECT_NULL)) {
                    723:                                        continue;
                    724:                                }
                    725:                                return;
                    726:                        }
                    727: 
                    728: #if    MIGHT_NOT_CACHE_SHADOWS
                    729:                        /*
                    730:                         *      Remove shadow now if we don't
                    731:                         *      want to cache shadows.
                    732:                         */
                    733:                        if (! cache_shadows) {
                    734:                                shadow = object->shadow;
                    735:                                object->shadow = VM_OBJECT_NULL;
                    736:                        }
                    737: #endif /* MIGHT_NOT_CACHE_SHADOWS */
                    738: 
                    739:                        /*
                    740:                         *      Enter the object onto the queue of
                    741:                         *      cached objects, and deactivate
                    742:                         *      all of its pages.
                    743:                         */
                    744:                        assert(object->shadow == VM_OBJECT_NULL);
                    745:                        VM_OBJ_RES_DECR(object);
                    746:                        XPR(XPR_VM_OBJECT,
                    747:                      "vm_o_deallocate: adding %x to cache, queue = (%x, %x)\n",
                    748:                                (integer_t)object,
                    749:                                (integer_t)vm_object_cached_list.next,
                    750:                                (integer_t)vm_object_cached_list.prev,0,0);
                    751: 
                    752:                        vm_object_cached_count++;
                    753:                        if (vm_object_cached_count > vm_object_cached_high)
                    754:                                vm_object_cached_high = vm_object_cached_count;
                    755:                        queue_enter(&vm_object_cached_list, object,
                    756:                                vm_object_t, cached_list);
                    757:                        vm_object_cache_unlock();
                    758:                        vm_object_deactivate_pages(object);
                    759:                        vm_object_unlock(object);
                    760: 
                    761: #if    MIGHT_NOT_CACHE_SHADOWS
                    762:                        /*
                    763:                         *      If we have a shadow that we need
                    764:                         *      to deallocate, do so now, remembering
                    765:                         *      to trim the cache later.
                    766:                         */
                    767:                        if (! cache_shadows && shadow != VM_OBJECT_NULL) {
                    768:                                object = shadow;
                    769:                                retry_cache_trim = TRUE;
                    770:                                continue;
                    771:                        }
                    772: #endif /* MIGHT_NOT_CACHE_SHADOWS */
                    773: 
                    774:                        /*
                    775:                         *      Trim the cache. If the cache trim
                    776:                         *      returns with a shadow for us to deallocate,
                    777:                         *      then remember to retry the cache trim
                    778:                         *      when we are done deallocating the shadow.
                    779:                         *      Otherwise, we are done.
                    780:                         */
                    781: 
                    782:                        object = vm_object_cache_trim(TRUE);
                    783:                        if (object == VM_OBJECT_NULL) {
                    784:                                return;
                    785:                        }
                    786:                        retry_cache_trim = TRUE;
                    787: 
                    788:                } else {
                    789:                        /*
                    790:                         *      This object is not cachable; terminate it.
                    791:                         */
                    792:                        XPR(XPR_VM_OBJECT,
                    793:         "vm_o_deallocate: !cacheable 0x%X res %d paging_ops %d thread 0x%lX ref %d\n",
                    794:                                (integer_t)object, object->resident_page_count,
                    795:                                object->paging_in_progress,
                    796:                                (natural_t)current_thread(),object->ref_count);
                    797: 
                    798:                        VM_OBJ_RES_DECR(object);        /* XXX ? */
                    799:                        /*
                    800:                         *      Terminate this object. If it had a shadow,
                    801:                         *      then deallocate it; otherwise, if we need
                    802:                         *      to retry a cache trim, do so now; otherwise,
                    803:                         *      we are done. "pageout" objects have a shadow,
                    804:                         *      but maintain a "paging reference" rather than
                    805:                         *      a normal reference.
                    806:                         */
                    807:                        shadow = object->pageout?VM_OBJECT_NULL:object->shadow;
                    808:                        vm_object_terminate(object);
                    809:                        if (shadow != VM_OBJECT_NULL) {
                    810:                                object = shadow;
                    811:                                continue;
                    812:                        }
                    813:                        if (retry_cache_trim &&
                    814:                            ((object = vm_object_cache_trim(TRUE)) !=
                    815:                             VM_OBJECT_NULL)) {
                    816:                                continue;
                    817:                        }
                    818:                        return;
                    819:                }
                    820:        }
                    821:        assert(! retry_cache_trim);
                    822: }
                    823: 
                    824: /*
                    825:  *     Check to see whether we really need to trim
                    826:  *     down the cache. If so, remove an object from
                    827:  *     the cache, terminate it, and repeat.
                    828:  *
                    829:  *     Called with, and returns with, cache lock unlocked.
                    830:  */
                    831: vm_object_t
                    832: vm_object_cache_trim(
                    833:        boolean_t called_from_vm_object_deallocate)
                    834: {
                    835:        register vm_object_t object = VM_OBJECT_NULL;
                    836:        vm_object_t shadow;
                    837: 
                    838:        for (;;) {
                    839: 
                    840:                /*
                    841:                 *      If we no longer need to trim the cache,
                    842:                 *      then we are done.
                    843:                 */
                    844: 
                    845:                vm_object_cache_lock();
                    846:                if (vm_object_cached_count <= vm_object_cached_max) {
                    847:                        vm_object_cache_unlock();
                    848:                        return VM_OBJECT_NULL;
                    849:                }
                    850: 
                    851:                /*
                    852:                 *      We must trim down the cache, so remove
                    853:                 *      the first object in the cache.
                    854:                 */
                    855:                XPR(XPR_VM_OBJECT,
                    856:                "vm_object_cache_trim: removing from front of cache (%x, %x)\n",
                    857:                        (integer_t)vm_object_cached_list.next,
                    858:                        (integer_t)vm_object_cached_list.prev, 0, 0, 0);
                    859: 
                    860:                object = (vm_object_t) queue_first(&vm_object_cached_list);
                    861:                vm_object_lock(object);
                    862:                queue_remove(&vm_object_cached_list, object, vm_object_t,
                    863:                             cached_list);
                    864:                vm_object_cached_count--;
                    865: 
                    866:                /*
                    867:                 *      Since this object is in the cache, we know
                    868:                 *      that it is initialized and has no references.
                    869:                 *      Take a reference to avoid recursive deallocations.
                    870:                 */
                    871: 
                    872:                assert(object->pager_initialized);
                    873:                assert(object->ref_count == 0);
                    874:                object->ref_count++;
                    875: 
                    876:                /*
                    877:                 *      Terminate the object.
                    878:                 *      If the object had a shadow, we let vm_object_deallocate
                    879:                 *      deallocate it. "pageout" objects have a shadow, but
                    880:                 *      maintain a "paging reference" rather than a normal
                    881:                 *      reference.
                    882:                 *      (We are careful here to limit recursion.)
                    883:                 */
                    884:                shadow = object->pageout?VM_OBJECT_NULL:object->shadow;
                    885:                vm_object_terminate(object);
                    886:                if (shadow != VM_OBJECT_NULL) {
                    887:                        if (called_from_vm_object_deallocate) {
                    888:                                return shadow;
                    889:                        } else {
                    890:                                vm_object_deallocate(shadow);
                    891:                        }
                    892:                }
                    893:        }
                    894: }
                    895: 
                    896: boolean_t      vm_object_terminate_remove_all = FALSE;
                    897: 
                    898: /*
                    899:  *     Routine:        vm_object_terminate
                    900:  *     Purpose:
                    901:  *             Free all resources associated with a vm_object.
                    902:  *     In/out conditions:
                    903:  *             Upon entry, the object and the cache must be locked,
                    904:  *             and the object must have exactly one reference.
                    905:  *
                    906:  *             The shadow object reference is left alone.
                    907:  *
                    908:  *             Upon exit, the cache will be unlocked, and the
                    909:  *             object will cease to exist.
                    910:  */
                    911: void
                    912: vm_object_terminate(
                    913:        register vm_object_t    object)
                    914: {
                    915:        register vm_page_t      p;
                    916:        vm_object_t             shadow_object;
                    917: 
                    918:        XPR(XPR_VM_OBJECT, "vm_object_terminate, object 0x%X ref %d\n",
                    919:                (integer_t)object, object->ref_count, 0, 0, 0);
                    920: 
                    921:        /*
                    922:         *      Make sure the object isn't already being terminated
                    923:         */
                    924: 
                    925:        assert(object->alive);
                    926:        object->alive = FALSE;
                    927: 
                    928:        /*
                    929:         *      Make sure no one can look us up now.
                    930:         */
                    931: 
                    932:        if(object->pager != IP_NULL) {
                    933:                vm_object_hash_entry_t  entry;
                    934: 
                    935:                entry = vm_object_hash_lookup(object->pager, FALSE);
                    936:                if (entry != VM_OBJECT_HASH_ENTRY_NULL)
                    937:                        entry->object = VM_OBJECT_NULL;
                    938:        }
                    939: 
                    940:        vm_object_cache_unlock();
                    941: 
                    942:        /*
                    943:         *      Detach the object from its shadow if we are the shadow's
                    944:         *      copy.
                    945:         */
                    946:        if (((shadow_object = object->shadow) != VM_OBJECT_NULL) &&
                    947:            !(object->pageout)) {
                    948:                vm_object_lock(shadow_object);
                    949:                assert((shadow_object->copy == object) ||
                    950:                       (shadow_object->copy == VM_OBJECT_NULL));
                    951:                shadow_object->copy = VM_OBJECT_NULL;
                    952:                vm_object_unlock(shadow_object);
                    953:        }
                    954: 
                    955:        /*
                    956:         *      The pageout daemon might be playing with our pages.
                    957:         *      Now that the object is dead, it won't touch any more
                    958:         *      pages, but some pages might already be on their way out.
                    959:         *      Hence, we wait until the active paging activities have ceased.
                    960:         */
                    961:        vm_object_paging_wait(object, THREAD_UNINT);
                    962:        object->ref_count--;
                    963: #if    TASK_SWAPPER
                    964:        assert(object->res_count == 0);
                    965: #endif /* TASK_SWAPPER */
                    966: 
                    967: Restart:
                    968:        assert (object->ref_count == 0);
                    969: 
                    970:        /*
                    971:         *      Clean or free the pages, as appropriate.
                    972:         *      It is possible for us to find busy/absent pages,
                    973:         *      if some faults on this object were aborted.
                    974:         */
                    975:        if (object->pageout) {
                    976:                assert(shadow_object != VM_OBJECT_NULL);
                    977:                assert(shadow_object == object->shadow);
                    978: 
                    979:                vm_pageout_object_terminate(object);
                    980: 
                    981:        } else if (object->temporary && ! object->can_persist ||
                    982:            object->pager == IP_NULL) {
                    983:                while (!queue_empty(&object->memq)) {
                    984:                        p = (vm_page_t) queue_first(&object->memq);
                    985: 
                    986:                        VM_PAGE_CHECK(p);
                    987: 
                    988:                        if (p->busy && !p->absent)
                    989:                                panic("vm_object_terminate.2 0x%x 0x%x",
                    990:                                      object, p);
                    991: 
                    992:                        VM_PAGE_FREE(p);
                    993:                }
                    994:        } else while (!queue_empty(&object->memq)) {
                    995:                /*
                    996:                 * Clear pager_trusted bit so that the pages get yanked
                    997:                 * out of the object instead of cleaned in place.  This
                    998:                 * prevents a deadlock in XMM and makes more sense anyway.
                    999:                 */
                   1000:                object->pager_trusted = FALSE;
                   1001: 
                   1002:                p = (vm_page_t) queue_first(&object->memq);
                   1003: 
                   1004:                VM_PAGE_CHECK(p);
                   1005: 
                   1006:                if (p->busy && !p->absent)
                   1007:                        panic("vm_object_terminate.3 0x%x 0x%x", object, p);
                   1008: 
                   1009:                vm_page_lock_queues();
                   1010:                VM_PAGE_QUEUES_REMOVE(p);
                   1011:                vm_page_unlock_queues();
                   1012: 
                   1013:                if (p->absent || p->private) {
                   1014: 
                   1015:                        /*
                   1016:                         *      For private pages, VM_PAGE_FREE just
                   1017:                         *      leaves the page structure around for
                   1018:                         *      its owner to clean up.  For absent
                   1019:                         *      pages, the structure is returned to
                   1020:                         *      the appropriate pool.
                   1021:                         */
                   1022: 
                   1023:                        goto free_page;
                   1024:                }
                   1025: 
                   1026:                if (p->fictitious)
                   1027:                        panic("vm_object_terminate.4 0x%x 0x%x", object, p);
                   1028: 
                   1029:                if (!p->dirty)
                   1030:                        p->dirty = pmap_is_modified(p->phys_addr);
                   1031: 
                   1032:                if (p->dirty || p->precious) {
                   1033:                        p->busy = TRUE;
                   1034:                        vm_object_paging_begin(object);
                   1035:                        vm_object_unlock(object);
                   1036:                        vm_pageout_cluster(p); /* flush page */
                   1037:                        vm_object_lock(object);
                   1038:                        vm_object_paging_wait(object, THREAD_UNINT);
                   1039: 
                   1040:                        XPR(XPR_VM_OBJECT,
                   1041:                            "vm_object_terminate restart, object 0x%X ref %d\n",
                   1042:                            (integer_t)object, object->ref_count, 0, 0, 0);
                   1043: 
                   1044:                        goto Restart;
                   1045:                } else {
                   1046:                    free_page:
                   1047:                        VM_PAGE_FREE(p);
                   1048:                }
                   1049:        }
                   1050: 
                   1051:        assert(object->paging_in_progress == 0);
                   1052:        assert(object->ref_count == 0);
                   1053: 
                   1054:        vm_object_remove(object);
                   1055: 
                   1056:        /*
                   1057:         *      Throw away port rights... note that they may
                   1058:         *      already have been thrown away (by vm_object_destroy
                   1059:         *      or memory_object_destroy).
                   1060:         *
                   1061:         *      Instead of destroying the control port,
                   1062:         *      we send all rights off to the memory manager,
                   1063:         *      using memory_object_terminate.
                   1064:         */
                   1065: 
                   1066:        vm_object_unlock(object);
                   1067:        if (object->pager != IP_NULL) {
                   1068:           /* consumes our rights for pager, pager_request */
                   1069:          memory_object_release(object->pager, object->pager_request);
                   1070:        }
                   1071: 
                   1072: #if    MACH_PAGEMAP
                   1073:        vm_external_destroy(object->existence_map, object->size);
                   1074: #endif /* MACH_PAGEMAP */
                   1075: 
                   1076:        /*
                   1077:         *      Free the space for the object.
                   1078:         */
                   1079: 
                   1080:        zfree(vm_object_zone, (vm_offset_t) object);
                   1081: }
                   1082: 
                   1083: /*
                   1084:  *     Routine:        vm_object_pager_wakeup
                   1085:  *     Purpose:        Wake up anyone waiting for termination of a pager.
                   1086:  */
                   1087: 
                   1088: void
                   1089: vm_object_pager_wakeup(
                   1090:        ipc_port_t      pager)
                   1091: {
                   1092:        vm_object_hash_entry_t  entry;
                   1093:        boolean_t               waiting = FALSE;
                   1094: 
                   1095:        /*
                   1096:         *      If anyone was waiting for the memory_object_terminate
                   1097:         *      to be queued, wake them up now.
                   1098:         */
                   1099:        vm_object_cache_lock();
                   1100:        entry = vm_object_hash_lookup(pager, TRUE);
                   1101:        if (entry != VM_OBJECT_HASH_ENTRY_NULL)
                   1102:                waiting = entry->waiting;
                   1103:        vm_object_cache_unlock();
                   1104:        if (entry != VM_OBJECT_HASH_ENTRY_NULL) {
                   1105:                if (waiting)
                   1106:                        thread_wakeup((event_t) pager);
                   1107:                vm_object_hash_entry_free(entry);
                   1108:        }
                   1109: }
                   1110: 
                   1111: /*
                   1112:  *     Routine:        memory_object_release
                   1113:  *     Purpose:        Terminate the pager and release port rights,
                   1114:  *                     just like memory_object_terminate, except
                   1115:  *                     that we wake up anyone blocked in vm_object_enter
                   1116:  *                     waiting for termination message to be queued
                   1117:  *                     before calling memory_object_init.
                   1118:  */
                   1119: void
                   1120: memory_object_release(
                   1121:        ipc_port_t      pager,
                   1122:        pager_request_t pager_request)
                   1123: {
                   1124: #ifdef MACH_BSD
                   1125:        kern_return_t vnode_pager_terminate(ipc_port_t, ipc_port_t);
                   1126: #endif
                   1127: 
                   1128:        /*
                   1129:         *      Keep a reference to pager port;
                   1130:         *      the terminate might otherwise release all references.
                   1131:         */
                   1132:        ipc_port_copy_send(pager);
                   1133: 
                   1134:        /*
                   1135:         *      Terminate the pager.
                   1136:         */
                   1137: 
                   1138: #ifdef MACH_BSD
                   1139:        if(((rpc_subsystem_t)pager_mux_hash_lookup(pager)) == 
                   1140:                ((rpc_subsystem_t) &vnode_pager_workaround)) {
                   1141:                (void) vnode_pager_terminate(pager, pager_request);
                   1142:        } else {
                   1143:                (void) memory_object_terminate(pager, pager_request);
                   1144:        }
                   1145: #else
                   1146:        (void) memory_object_terminate(pager, pager_request);
                   1147: #endif
                   1148: 
                   1149:        /*
                   1150:         *      Wakeup anyone waiting for this terminate
                   1151:         */
                   1152:        vm_object_pager_wakeup(pager);
                   1153: 
                   1154:        /*
                   1155:         *      Release reference to pager port.
                   1156:         */
                   1157:        ipc_port_release_send(pager);
                   1158: }
                   1159: 
                   1160: /*
                   1161:  *     Routine:        vm_object_abort_activity [internal use only]
                   1162:  *     Purpose:
                   1163:  *             Abort paging requests pending on this object.
                   1164:  *     In/out conditions:
                   1165:  *             The object is locked on entry and exit.
                   1166:  */
                   1167: void
                   1168: vm_object_abort_activity(
                   1169:        vm_object_t     object)
                   1170: {
                   1171:        register
                   1172:        vm_page_t       p;
                   1173:        vm_page_t       next;
                   1174: 
                   1175:        XPR(XPR_VM_OBJECT, "vm_object_abort_activity, object 0x%X\n",
                   1176:                (integer_t)object, 0, 0, 0, 0);
                   1177: 
                   1178:        /*
                   1179:         *      Abort all activity that would be waiting
                   1180:         *      for a result on this memory object.
                   1181:         *
                   1182:         *      We could also choose to destroy all pages
                   1183:         *      that we have in memory for this object, but
                   1184:         *      we don't.
                   1185:         */
                   1186: 
                   1187:        p = (vm_page_t) queue_first(&object->memq);
                   1188:        while (!queue_end(&object->memq, (queue_entry_t) p)) {
                   1189:                next = (vm_page_t) queue_next(&p->listq);
                   1190: 
                   1191:                /*
                   1192:                 *      If it's being paged in, destroy it.
                   1193:                 *      If an unlock has been requested, start it again.
                   1194:                 */
                   1195: 
                   1196:                if (p->busy && p->absent) {
                   1197:                        VM_PAGE_FREE(p);
                   1198:                }
                   1199:                 else {
                   1200:                        if (p->unlock_request != VM_PROT_NONE)
                   1201:                                p->unlock_request = VM_PROT_NONE;
                   1202:                        PAGE_WAKEUP(p);
                   1203:                }
                   1204:                
                   1205:                p = next;
                   1206:        }
                   1207: 
                   1208:        /*
                   1209:         *      Wake up threads waiting for the memory object to
                   1210:         *      become ready.
                   1211:         */
                   1212: 
                   1213:        object->pager_ready = TRUE;
                   1214:        vm_object_wakeup(object, VM_OBJECT_EVENT_PAGER_READY);
                   1215: }
                   1216: 
                   1217: /*
                   1218:  *     Routine:        memory_object_destroy [user interface]
                   1219:  *     Purpose:
                   1220:  *             Shut down a memory object, despite the
                   1221:  *             presence of address map (or other) references
                   1222:  *             to the vm_object.
                   1223:  */
                   1224: kern_return_t
                   1225: memory_object_destroy(
                   1226:        register vm_object_t    object,
                   1227:        kern_return_t           reason)
                   1228: {
                   1229:        ipc_port_t      old_object;
                   1230:        pager_request_t old_pager_request;
                   1231: 
                   1232: #ifdef lint
                   1233:        reason++;
                   1234: #endif /* lint */
                   1235: 
                   1236:        if (object == VM_OBJECT_NULL)
                   1237:                return(KERN_SUCCESS);
                   1238: 
                   1239:        /*
                   1240:         *      Remove the port associations immediately.
                   1241:         *
                   1242:         *      This will prevent the memory manager from further
                   1243:         *      meddling.  [If it wanted to flush data or make
                   1244:         *      other changes, it should have done so before performing
                   1245:         *      the destroy call.]
                   1246:         */
                   1247: 
                   1248:        vm_object_cache_lock();
                   1249:        vm_object_lock(object);
                   1250:        vm_object_remove(object);
                   1251:        object->can_persist = FALSE;
                   1252:        vm_object_cache_unlock();
                   1253: 
                   1254:        /*
                   1255:         *      Rip out the ports from the vm_object now... this
                   1256:         *      will prevent new memory_object calls from succeeding.
                   1257:         */
                   1258: 
                   1259:        old_object = object->pager;
                   1260:        old_pager_request = object->pager_request;
                   1261: 
                   1262:        object->pager = IP_NULL;
                   1263:        object->pager_request = PAGER_REQUEST_NULL;
                   1264: 
                   1265:        /*
                   1266:         *      Wait for existing paging activity (that might
                   1267:         *      have the old ports) to subside.
                   1268:         */
                   1269: 
                   1270:        vm_object_paging_wait(object, THREAD_UNINT);
                   1271:        vm_object_unlock(object);
                   1272: 
                   1273:        /*
                   1274:         *      Shut down the ports now.
                   1275:         *
                   1276:         *      [Paging operations may be proceeding concurrently --
                   1277:         *      they'll get the null values established above.]
                   1278:         */
                   1279: 
                   1280:        if (old_object != IP_NULL) {
                   1281:                /* consumes our rights for object, control */
                   1282:                memory_object_release(old_object, old_pager_request);
                   1283:        }
                   1284: 
                   1285:        /*
                   1286:         *      Lose the reference that was donated for this routine
                   1287:         */
                   1288: 
                   1289:        vm_object_deallocate(object);
                   1290: 
                   1291:        return(KERN_SUCCESS);
                   1292: }
                   1293: 
                   1294: /*
                   1295:  *     vm_object_deactivate_pages
                   1296:  *
                   1297:  *     Deactivate all pages in the specified object.  (Keep its pages
                   1298:  *     in memory even though it is no longer referenced.)
                   1299:  *
                   1300:  *     The object must be locked.
                   1301:  */
                   1302: void
                   1303: vm_object_deactivate_pages(
                   1304:        register vm_object_t    object)
                   1305: {
                   1306:        register vm_page_t      p;
                   1307: 
                   1308:        queue_iterate(&object->memq, p, vm_page_t, listq) {
                   1309:                vm_page_lock_queues();
                   1310:                if (!p->busy)
                   1311:                        vm_page_deactivate(p);
                   1312:                vm_page_unlock_queues();
                   1313:        }
                   1314: }
                   1315: 
                   1316: 
                   1317: /*
                   1318:  *     Routine:        vm_object_pmap_protect
                   1319:  *
                   1320:  *     Purpose:
                   1321:  *             Reduces the permission for all physical
                   1322:  *             pages in the specified object range.
                   1323:  *
                   1324:  *             If removing write permission only, it is
                   1325:  *             sufficient to protect only the pages in
                   1326:  *             the top-level object; only those pages may
                   1327:  *             have write permission.
                   1328:  *
                   1329:  *             If removing all access, we must follow the
                   1330:  *             shadow chain from the top-level object to
                   1331:  *             remove access to all pages in shadowed objects.
                   1332:  *
                   1333:  *             The object must *not* be locked.  The object must
                   1334:  *             be temporary/internal.  
                   1335:  *
                   1336:  *              If pmap is not NULL, this routine assumes that
                   1337:  *              the only mappings for the pages are in that
                   1338:  *              pmap.
                   1339:  */
                   1340: 
                   1341: void
                   1342: vm_object_pmap_protect(
                   1343:        register vm_object_t    object,
                   1344:        register vm_offset_t    offset,
                   1345:        vm_offset_t             size,
                   1346:        pmap_t                  pmap,
                   1347:        vm_offset_t             pmap_start,
                   1348:        vm_prot_t               prot)
                   1349: {
                   1350:        if (object == VM_OBJECT_NULL)
                   1351:            return;
                   1352: 
                   1353:        vm_object_lock(object);
                   1354: 
                   1355:        assert(object->copy_strategy == MEMORY_OBJECT_COPY_SYMMETRIC);
                   1356: 
                   1357:        while (TRUE) {
                   1358:            if (object->resident_page_count > atop(size) / 2 &&
                   1359:                    pmap != PMAP_NULL) {
                   1360:                vm_object_unlock(object);
                   1361:                pmap_protect(pmap, pmap_start, pmap_start + size, prot);
                   1362:                return;
                   1363:            }
                   1364: 
                   1365:            {
                   1366:                register vm_page_t      p;
                   1367:                register vm_offset_t    end;
                   1368: 
                   1369:                end = offset + size;
                   1370: 
                   1371:                if (pmap != PMAP_NULL) {
                   1372:                  queue_iterate(&object->memq, p, vm_page_t, listq) {
                   1373:                    if (!p->fictitious &&
                   1374:                        (offset <= p->offset) && (p->offset < end)) {
                   1375: 
                   1376:                        vm_offset_t start = pmap_start + (p->offset - offset);
                   1377: 
                   1378:                        pmap_protect(pmap, start, start + PAGE_SIZE, prot);
                   1379:                    }
                   1380:                  }
                   1381:                } else {
                   1382:                  queue_iterate(&object->memq, p, vm_page_t, listq) {
                   1383:                    if (!p->fictitious &&
                   1384:                        (offset <= p->offset) && (p->offset < end)) {
                   1385: 
                   1386:                            pmap_page_protect(p->phys_addr,
                   1387:                                              prot & ~p->page_lock);
                   1388:                    }
                   1389:                  }
                   1390:                }
                   1391:            }
                   1392: 
                   1393:            if (prot == VM_PROT_NONE) {
                   1394:                /*
                   1395:                 * Must follow shadow chain to remove access
                   1396:                 * to pages in shadowed objects.
                   1397:                 */
                   1398:                register vm_object_t    next_object;
                   1399: 
                   1400:                next_object = object->shadow;
                   1401:                if (next_object != VM_OBJECT_NULL) {
                   1402:                    offset += object->shadow_offset;
                   1403:                    vm_object_lock(next_object);
                   1404:                    vm_object_unlock(object);
                   1405:                    object = next_object;
                   1406:                }
                   1407:                else {
                   1408:                    /*
                   1409:                     * End of chain - we are done.
                   1410:                     */
                   1411:                    break;
                   1412:                }
                   1413:            }
                   1414:            else {
                   1415:                /*
                   1416:                 * Pages in shadowed objects may never have
                   1417:                 * write permission - we may stop here.
                   1418:                 */
                   1419:                break;
                   1420:            }
                   1421:        }
                   1422: 
                   1423:        vm_object_unlock(object);
                   1424: }
                   1425: 
                   1426: /*
                   1427:  *     Routine:        vm_object_copy_slowly
                   1428:  *
                   1429:  *     Description:
                   1430:  *             Copy the specified range of the source
                   1431:  *             virtual memory object without using
                   1432:  *             protection-based optimizations (such
                   1433:  *             as copy-on-write).  The pages in the
                   1434:  *             region are actually copied.
                   1435:  *
                   1436:  *     In/out conditions:
                   1437:  *             The caller must hold a reference and a lock
                   1438:  *             for the source virtual memory object.  The source
                   1439:  *             object will be returned *unlocked*.
                   1440:  *
                   1441:  *     Results:
                   1442:  *             If the copy is completed successfully, KERN_SUCCESS is
                   1443:  *             returned.  If the caller asserted the interruptible
                   1444:  *             argument, and an interruption occurred while waiting
                   1445:  *             for a user-generated event, MACH_SEND_INTERRUPTED is
                   1446:  *             returned.  Other values may be returned to indicate
                   1447:  *             hard errors during the copy operation.
                   1448:  *
                   1449:  *             A new virtual memory object is returned in a
                   1450:  *             parameter (_result_object).  The contents of this
                   1451:  *             new object, starting at a zero offset, are a copy
                   1452:  *             of the source memory region.  In the event of
                   1453:  *             an error, this parameter will contain the value
                   1454:  *             VM_OBJECT_NULL.
                   1455:  */
                   1456: kern_return_t
                   1457: vm_object_copy_slowly(
                   1458:        register vm_object_t    src_object,
                   1459:        vm_offset_t             src_offset,
                   1460:        vm_size_t               size,
                   1461:        boolean_t               interruptible,
                   1462:        vm_object_t             *_result_object)        /* OUT */
                   1463: {
                   1464:        vm_object_t     new_object;
                   1465:        vm_offset_t     new_offset;
                   1466: 
                   1467:        vm_offset_t     src_lo_offset = src_offset;
                   1468:        vm_offset_t     src_hi_offset = src_offset + size;
                   1469: 
                   1470:        XPR(XPR_VM_OBJECT, "v_o_c_slowly obj 0x%x off 0x%x size 0x%x\n",
                   1471:            src_object, src_offset, size, 0, 0);
                   1472: 
                   1473:        if (size == 0) {
                   1474:                vm_object_unlock(src_object);
                   1475:                *_result_object = VM_OBJECT_NULL;
                   1476:                return(KERN_INVALID_ARGUMENT);
                   1477:        }
                   1478: 
                   1479:        /*
                   1480:         *      Prevent destruction of the source object while we copy.
                   1481:         */
                   1482: 
                   1483:        assert(src_object->ref_count > 0);
                   1484:        src_object->ref_count++;
                   1485:        VM_OBJ_RES_INCR(src_object);
                   1486:        vm_object_unlock(src_object);
                   1487: 
                   1488:        /*
                   1489:         *      Create a new object to hold the copied pages.
                   1490:         *      A few notes:
                   1491:         *              We fill the new object starting at offset 0,
                   1492:         *               regardless of the input offset.
                   1493:         *              We don't bother to lock the new object within
                   1494:         *               this routine, since we have the only reference.
                   1495:         */
                   1496: 
                   1497:        new_object = vm_object_allocate(size);
                   1498:        new_offset = 0;
                   1499: 
                   1500:        assert(size == trunc_page(size));       /* Will the loop terminate? */
                   1501: 
                   1502:        for ( ;
                   1503:            size != 0 ;
                   1504:            src_offset += PAGE_SIZE, new_offset += PAGE_SIZE, size -= PAGE_SIZE
                   1505:            ) {
                   1506:                vm_page_t       new_page;
                   1507:                vm_fault_return_t result;
                   1508: 
                   1509:                while ((new_page = vm_page_alloc(new_object, new_offset))
                   1510:                                == VM_PAGE_NULL) {
                   1511:                        VM_PAGE_WAIT();
                   1512:                }
                   1513: 
                   1514:                do {
                   1515:                        vm_prot_t       prot = VM_PROT_READ;
                   1516:                        vm_page_t       _result_page;
                   1517:                        vm_page_t       top_page;
                   1518:                        register
                   1519:                        vm_page_t       result_page;
                   1520:                        kern_return_t   error_code;
                   1521: 
                   1522:                        vm_object_lock(src_object);
                   1523:                        vm_object_paging_begin(src_object);
                   1524: 
                   1525:                        XPR(XPR_VM_FAULT,"vm_object_copy_slowly -> vm_fault_page",0,0,0,0,0);
                   1526:                        result = vm_fault_page(src_object, src_offset,
                   1527:                                VM_PROT_READ, FALSE, interruptible,
                   1528:                                src_lo_offset, src_hi_offset,
                   1529:                                VM_BEHAVIOR_SEQUENTIAL,
                   1530:                                &prot, &_result_page, &top_page,
                   1531:                                (int *)0,
                   1532:                                &error_code, FALSE, FALSE);
                   1533: 
                   1534:                        switch(result) {
                   1535:                                case VM_FAULT_SUCCESS:
                   1536:                                        result_page = _result_page;
                   1537: 
                   1538:                                        /*
                   1539:                                         *      We don't need to hold the object
                   1540:                                         *      lock -- the busy page will be enough.
                   1541:                                         *      [We don't care about picking up any
                   1542:                                         *      new modifications.]
                   1543:                                         *
                   1544:                                         *      Copy the page to the new object.
                   1545:                                         *
                   1546:                                         *      POLICY DECISION:
                   1547:                                         *              If result_page is clean,
                   1548:                                         *              we could steal it instead
                   1549:                                         *              of copying.
                   1550:                                         */
                   1551: 
                   1552:                                        vm_object_unlock(result_page->object);
                   1553:                                        vm_page_copy(result_page, new_page);
                   1554: 
                   1555:                                        /*
                   1556:                                         *      Let go of both pages (make them
                   1557:                                         *      not busy, perform wakeup, activate).
                   1558:                                         */
                   1559: 
                   1560:                                        new_page->busy = FALSE;
                   1561:                                        new_page->dirty = TRUE;
                   1562:                                        vm_object_lock(result_page->object);
                   1563:                                        PAGE_WAKEUP_DONE(result_page);
                   1564: 
                   1565:                                        vm_page_lock_queues();
                   1566:                                        if (!result_page->active &&
                   1567:                                            !result_page->inactive)
                   1568:                                                vm_page_activate(result_page);
                   1569:                                        vm_page_activate(new_page);
                   1570:                                        vm_page_unlock_queues();
                   1571: 
                   1572:                                        /*
                   1573:                                         *      Release paging references and
                   1574:                                         *      top-level placeholder page, if any.
                   1575:                                         */
                   1576: 
                   1577:                                        vm_fault_cleanup(result_page->object,
                   1578:                                                        top_page);
                   1579: 
                   1580:                                        break;
                   1581:                                
                   1582:                                case VM_FAULT_RETRY:
                   1583:                                        break;
                   1584: 
                   1585:                                case VM_FAULT_MEMORY_SHORTAGE:
                   1586:                                        VM_PAGE_WAIT();
                   1587:                                        break;
                   1588: 
                   1589:                                case VM_FAULT_FICTITIOUS_SHORTAGE:
                   1590:                                        vm_page_more_fictitious();
                   1591:                                        break;
                   1592: 
                   1593:                                case VM_FAULT_INTERRUPTED:
                   1594:                                        vm_page_free(new_page);
                   1595:                                        vm_object_deallocate(new_object);
                   1596:                                        vm_object_deallocate(src_object);
                   1597:                                        *_result_object = VM_OBJECT_NULL;
                   1598:                                        return(MACH_SEND_INTERRUPTED);
                   1599: 
                   1600:                                case VM_FAULT_MEMORY_ERROR:
                   1601:                                        /*
                   1602:                                         * A policy choice:
                   1603:                                         *      (a) ignore pages that we can't
                   1604:                                         *          copy
                   1605:                                         *      (b) return the null object if
                   1606:                                         *          any page fails [chosen]
                   1607:                                         */
                   1608: 
                   1609:                                        vm_page_free(new_page);
                   1610:                                        vm_object_deallocate(new_object);
                   1611:                                        vm_object_deallocate(src_object);
                   1612:                                        *_result_object = VM_OBJECT_NULL;
                   1613:                                        return(error_code ? error_code:
                   1614:                                                KERN_MEMORY_ERROR);
                   1615:                        }
                   1616:                } while (result != VM_FAULT_SUCCESS);
                   1617:        }
                   1618: 
                   1619:        /*
                   1620:         *      Lose the extra reference, and return our object.
                   1621:         */
                   1622: 
                   1623:        vm_object_deallocate(src_object);
                   1624:        *_result_object = new_object;
                   1625:        return(KERN_SUCCESS);
                   1626: }
                   1627: 
                   1628: /*
                   1629:  *     Routine:        vm_object_copy_quickly
                   1630:  *
                   1631:  *     Purpose:
                   1632:  *             Copy the specified range of the source virtual
                   1633:  *             memory object, if it can be done without waiting
                   1634:  *             for user-generated events.
                   1635:  *
                   1636:  *     Results:
                   1637:  *             If the copy is successful, the copy is returned in
                   1638:  *             the arguments; otherwise, the arguments are not
                   1639:  *             affected.
                   1640:  *
                   1641:  *     In/out conditions:
                   1642:  *             The object should be unlocked on entry and exit.
                   1643:  */
                   1644: 
                   1645: /*ARGSUSED*/
                   1646: boolean_t
                   1647: vm_object_copy_quickly(
                   1648:        vm_object_t     *_object,               /* INOUT */
                   1649:        vm_offset_t     offset,                 /* IN */
                   1650:        vm_size_t       size,                   /* IN */
                   1651:        boolean_t       *_src_needs_copy,       /* OUT */
                   1652:        boolean_t       *_dst_needs_copy)       /* OUT */
                   1653: {
                   1654:        vm_object_t     object = *_object;
                   1655:        memory_object_copy_strategy_t copy_strategy;
                   1656: 
                   1657:        XPR(XPR_VM_OBJECT, "v_o_c_quickly obj 0x%x off 0x%x size 0x%x\n",
                   1658:            *_object, offset, size, 0, 0);
                   1659:        if (object == VM_OBJECT_NULL) {
                   1660:                *_src_needs_copy = FALSE;
                   1661:                *_dst_needs_copy = FALSE;
                   1662:                return(TRUE);
                   1663:        }
                   1664: 
                   1665:        vm_object_lock(object);
                   1666: 
                   1667:        copy_strategy = object->copy_strategy;
                   1668: 
                   1669:        switch (copy_strategy) {
                   1670:        case MEMORY_OBJECT_COPY_SYMMETRIC:
                   1671: 
                   1672:                /*
                   1673:                 *      Symmetric copy strategy.
                   1674:                 *      Make another reference to the object.
                   1675:                 *      Leave object/offset unchanged.
                   1676:                 */
                   1677: 
                   1678:                assert(object->ref_count > 0);
                   1679:                object->ref_count++;
                   1680:                vm_object_res_reference(object);
                   1681:                object->shadowed = TRUE;
                   1682:                vm_object_unlock(object);
                   1683: 
                   1684:                /*
                   1685:                 *      Both source and destination must make
                   1686:                 *      shadows, and the source must be made
                   1687:                 *      read-only if not already.
                   1688:                 */
                   1689: 
                   1690:                *_src_needs_copy = TRUE;
                   1691:                *_dst_needs_copy = TRUE;
                   1692: 
                   1693:                break;
                   1694: 
                   1695:        case MEMORY_OBJECT_COPY_DELAY:
                   1696:                vm_object_unlock(object);
                   1697:                return(FALSE);
                   1698: 
                   1699:        default:
                   1700:                vm_object_unlock(object);
                   1701:                return(FALSE);
                   1702:        }
                   1703:        return(TRUE);
                   1704: }
                   1705: 
                   1706: int copy_call_count = 0;
                   1707: int copy_call_sleep_count = 0;
                   1708: int copy_call_restart_count = 0;
                   1709: 
                   1710: /*
                   1711:  *     Routine:        vm_object_copy_call [internal]
                   1712:  *
                   1713:  *     Description:
                   1714:  *             Copy the source object (src_object), using the
                   1715:  *             user-managed copy algorithm.
                   1716:  *
                   1717:  *     In/out conditions:
                   1718:  *             The source object must be locked on entry.  It
                   1719:  *             will be *unlocked* on exit.
                   1720:  *
                   1721:  *     Results:
                   1722:  *             If the copy is successful, KERN_SUCCESS is returned.
                   1723:  *             A new object that represents the copied virtual
                   1724:  *             memory is returned in a parameter (*_result_object).
                   1725:  *             If the return value indicates an error, this parameter
                   1726:  *             is not valid.
                   1727:  */
                   1728: kern_return_t
                   1729: vm_object_copy_call(
                   1730:        vm_object_t     src_object,
                   1731:        vm_offset_t     src_offset,
                   1732:        vm_size_t       size,
                   1733:        vm_object_t     *_result_object)        /* OUT */
                   1734: {
                   1735:        kern_return_t   kr;
                   1736:        vm_object_t     copy;
                   1737:        boolean_t       check_ready = FALSE;
                   1738: 
                   1739:        /*
                   1740:         *      If a copy is already in progress, wait and retry.
                   1741:         *
                   1742:         *      XXX
                   1743:         *      Consider making this call interruptable, as Mike
                   1744:         *      intended it to be.
                   1745:         *
                   1746:         *      XXXO
                   1747:         *      Need a counter or version or something to allow
                   1748:         *      us to use the copy that the currently requesting
                   1749:         *      thread is obtaining -- is it worth adding to the
                   1750:         *      vm object structure? Depends how common this case it.
                   1751:         */
                   1752:        copy_call_count++;
                   1753:        while (vm_object_wanted(src_object, VM_OBJECT_EVENT_COPY_CALL)) {
                   1754:                vm_object_wait(src_object, VM_OBJECT_EVENT_COPY_CALL,
                   1755:                               THREAD_UNINT);
                   1756:                vm_object_lock(src_object);
                   1757:                copy_call_restart_count++;
                   1758:        }
                   1759: 
                   1760:        /*
                   1761:         *      Indicate (for the benefit of memory_object_create_copy)
                   1762:         *      that we want a copy for src_object. (Note that we cannot
                   1763:         *      do a real assert_wait before calling memory_object_copy,
                   1764:         *      so we simply set the flag.)
                   1765:         */
                   1766: 
                   1767:        vm_object_set_wanted(src_object, VM_OBJECT_EVENT_COPY_CALL);
                   1768:        vm_object_unlock(src_object);
                   1769: 
                   1770:        /*
                   1771:         *      Ask the memory manager to give us a memory object
                   1772:         *      which represents a copy of the src object.
                   1773:         *      The memory manager may give us a memory object
                   1774:         *      which we already have, or it may give us a
                   1775:         *      new memory object. This memory object will arrive
                   1776:         *      via memory_object_create_copy.
                   1777:         */
                   1778: 
                   1779:        kr = KERN_FAILURE;      /* XXX need to change memory_object.defs */
                   1780:        if (kr != KERN_SUCCESS) {
                   1781:                return kr;
                   1782:        }
                   1783: 
                   1784:        /*
                   1785:         *      Wait for the copy to arrive.
                   1786:         */
                   1787:        vm_object_lock(src_object);
                   1788:        while (vm_object_wanted(src_object, VM_OBJECT_EVENT_COPY_CALL)) {
                   1789:                vm_object_wait(src_object, VM_OBJECT_EVENT_COPY_CALL,
                   1790:                               THREAD_UNINT);
                   1791:                vm_object_lock(src_object);
                   1792:                copy_call_sleep_count++;
                   1793:        }
                   1794: Retry:
                   1795:        assert(src_object->copy != VM_OBJECT_NULL);
                   1796:        copy = src_object->copy;
                   1797:        if (!vm_object_lock_try(copy)) {
                   1798:                vm_object_unlock(src_object);
                   1799:                mutex_pause();  /* wait a bit */
                   1800:                vm_object_lock(src_object);
                   1801:                goto Retry;
                   1802:        }
                   1803:        if (copy->size < src_offset+size)
                   1804:                copy->size = src_offset+size;
                   1805: 
                   1806:        if (!copy->pager_ready)
                   1807:                check_ready = TRUE;
                   1808: 
                   1809:        /*
                   1810:         *      Return the copy.
                   1811:         */
                   1812:        *_result_object = copy;
                   1813:        vm_object_unlock(copy);
                   1814:        vm_object_unlock(src_object);
                   1815: 
                   1816:        /* Wait for the copy to be ready. */
                   1817:        if (check_ready == TRUE) {
                   1818:                vm_object_lock(copy);
                   1819:                while (!copy->pager_ready) {
                   1820:                        vm_object_wait(copy, VM_OBJECT_EVENT_PAGER_READY,
                   1821:                                                                        FALSE);
                   1822:                        vm_object_lock(copy);
                   1823:                }
                   1824:                vm_object_unlock(copy);
                   1825:        }
                   1826: 
                   1827:        return KERN_SUCCESS;
                   1828: }
                   1829: 
                   1830: int copy_delayed_lock_collisions = 0;
                   1831: int copy_delayed_max_collisions = 0;
                   1832: int copy_delayed_lock_contention = 0;
                   1833: int copy_delayed_protect_iterate = 0;
                   1834: int copy_delayed_protect_lookup = 0;
                   1835: int copy_delayed_protect_lookup_wait = 0;
                   1836: 
                   1837: /*
                   1838:  *     Routine:        vm_object_copy_delayed [internal]
                   1839:  *
                   1840:  *     Description:
                   1841:  *             Copy the specified virtual memory object, using
                   1842:  *             the asymmetric copy-on-write algorithm.
                   1843:  *
                   1844:  *     In/out conditions:
                   1845:  *             The object must be unlocked on entry.
                   1846:  *
                   1847:  *             This routine will not block waiting for user-generated
                   1848:  *             events.  It is not interruptible.
                   1849:  */
                   1850: vm_object_t
                   1851: vm_object_copy_delayed(
                   1852:        vm_object_t     src_object,
                   1853:        vm_offset_t     src_offset,
                   1854:        vm_size_t       size)
                   1855: {
                   1856:        vm_object_t     new_copy = VM_OBJECT_NULL;
                   1857:        vm_object_t     old_copy;
                   1858:        vm_page_t       p;
                   1859:        vm_size_t       copy_size;
                   1860: 
                   1861:        int collisions = 0;
                   1862:        /*
                   1863:         *      The user-level memory manager wants to see all of the changes
                   1864:         *      to this object, but it has promised not to make any changes on
                   1865:         *      its own.
                   1866:         *
                   1867:         *      Perform an asymmetric copy-on-write, as follows:
                   1868:         *              Create a new object, called a "copy object" to hold
                   1869:         *               pages modified by the new mapping  (i.e., the copy,
                   1870:         *               not the original mapping).
                   1871:         *              Record the original object as the backing object for
                   1872:         *               the copy object.  If the original mapping does not
                   1873:         *               change a page, it may be used read-only by the copy.
                   1874:         *              Record the copy object in the original object.
                   1875:         *               When the original mapping causes a page to be modified,
                   1876:         *               it must be copied to a new page that is "pushed" to
                   1877:         *               the copy object.
                   1878:         *              Mark the new mapping (the copy object) copy-on-write.
                   1879:         *               This makes the copy object itself read-only, allowing
                   1880:         *               it to be reused if the original mapping makes no
                   1881:         *               changes, and simplifying the synchronization required
                   1882:         *               in the "push" operation described above.
                   1883:         *
                   1884:         *      The copy-on-write is said to be assymetric because the original
                   1885:         *      object is *not* marked copy-on-write. A copied page is pushed
                   1886:         *      to the copy object, regardless which party attempted to modify
                   1887:         *      the page.
                   1888:         *
                   1889:         *      Repeated asymmetric copy operations may be done. If the
                   1890:         *      original object has not been changed since the last copy, its
                   1891:         *      copy object can be reused. Otherwise, a new copy object can be
                   1892:         *      inserted between the original object and its previous copy
                   1893:         *      object.  Since any copy object is read-only, this cannot affect
                   1894:         *      affect the contents of the previous copy object.
                   1895:         *
                   1896:         *      Note that a copy object is higher in the object tree than the
                   1897:         *      original object; therefore, use of the copy object recorded in
                   1898:         *      the original object must be done carefully, to avoid deadlock.
                   1899:         */
                   1900: 
                   1901:  Retry:
                   1902:        vm_object_lock(src_object);
                   1903:  
                   1904:        /*
                   1905:         *      See whether we can reuse the result of a previous
                   1906:         *      copy operation.
                   1907:         */
                   1908: 
                   1909:        old_copy = src_object->copy;
                   1910:        if (old_copy != VM_OBJECT_NULL) {
                   1911:                /*
                   1912:                 *      Try to get the locks (out of order)
                   1913:                 */
                   1914:                if (!vm_object_lock_try(old_copy)) {
                   1915:                        vm_object_unlock(src_object);
                   1916:                        mutex_pause();
                   1917: 
                   1918:                        /* Heisenberg Rules */
                   1919:                        copy_delayed_lock_collisions++;
                   1920:                        if (collisions++ == 0)
                   1921:                                copy_delayed_lock_contention++;
                   1922: 
                   1923:                        if (collisions > copy_delayed_max_collisions)
                   1924:                                copy_delayed_max_collisions = collisions;
                   1925: 
                   1926:                        goto Retry;
                   1927:                }
                   1928: 
                   1929:                /*
                   1930:                 *      Determine whether the old copy object has
                   1931:                 *      been modified.
                   1932:                 */
                   1933: 
                   1934:                if (old_copy->resident_page_count == 0 &&
                   1935:                    !old_copy->pager_created) {
                   1936:                        /*
                   1937:                         *      It has not been modified.
                   1938:                         *
                   1939:                         *      Return another reference to
                   1940:                         *      the existing copy-object.
                   1941:                         */
                   1942:                        assert(old_copy->ref_count > 0);
                   1943:                        old_copy->ref_count++;
                   1944: 
                   1945:                        if (old_copy->size < src_offset+size)
                   1946:                                old_copy->size = src_offset+size;
                   1947: 
                   1948: #if    TASK_SWAPPER
                   1949:                        /*
                   1950:                         * We have to reproduce some of the code from
                   1951:                         * vm_object_res_reference because we've taken
                   1952:                         * the locks out of order here, and deadlock
                   1953:                         * would result if we simply called that function.
                   1954:                         */
                   1955:                        if (++old_copy->res_count == 1) {
                   1956:                                assert(old_copy->shadow == src_object);
                   1957:                                vm_object_res_reference(src_object);
                   1958:                        }
                   1959: #endif /* TASK_SWAPPER */
                   1960: 
                   1961:                        vm_object_unlock(old_copy);
                   1962:                        vm_object_unlock(src_object);
                   1963: 
                   1964:                        if (new_copy != VM_OBJECT_NULL) {
                   1965:                                vm_object_unlock(new_copy);
                   1966:                                vm_object_deallocate(new_copy);
                   1967:                        }
                   1968: 
                   1969:                        return(old_copy);
                   1970:                }
                   1971:                if (new_copy == VM_OBJECT_NULL) {
                   1972:                        vm_object_unlock(old_copy);
                   1973:                        vm_object_unlock(src_object);
                   1974:                        new_copy = vm_object_allocate(src_offset + size);
                   1975:                        vm_object_lock(new_copy);
                   1976:                        goto Retry;
                   1977:                }
                   1978: 
                   1979:                /*
                   1980:                 * Adjust the size argument so that the newly-created 
                   1981:                 * copy object will be large enough to back either the
                   1982:                 * new old copy object or the new mapping.
                   1983:                 */
                   1984:                if (old_copy->size > src_offset+size)
                   1985:                        size =  old_copy->size - src_offset;
                   1986: 
                   1987:                /*
                   1988:                 *      The copy-object is always made large enough to
                   1989:                 *      completely shadow the original object, since
                   1990:                 *      it may have several users who want to shadow
                   1991:                 *      the original object at different points.
                   1992:                 */
                   1993: 
                   1994:                assert((old_copy->shadow == src_object) &&
                   1995:                    (old_copy->shadow_offset == (vm_offset_t) 0));
                   1996: 
                   1997:                /*
                   1998:                 *      Make the old copy-object shadow the new one.
                   1999:                 *      It will receive no more pages from the original
                   2000:                 *      object.
                   2001:                 */
                   2002: 
                   2003:                src_object->ref_count--;        /* remove ref. from old_copy */
                   2004:                assert(src_object->ref_count > 0);
                   2005:                old_copy->shadow = new_copy;
                   2006:                assert(new_copy->ref_count > 0);
                   2007:                new_copy->ref_count++;          /* for old_copy->shadow ref. */
                   2008: 
                   2009: #if TASK_SWAPPER
                   2010:                if (old_copy->res_count) {
                   2011:                        VM_OBJ_RES_INCR(new_copy);
                   2012:                        VM_OBJ_RES_DECR(src_object);
                   2013:                }
                   2014: #endif
                   2015: 
                   2016:                vm_object_unlock(old_copy);     /* done with old_copy */
                   2017:        } else if (new_copy == VM_OBJECT_NULL) {
                   2018:                vm_object_unlock(src_object);
                   2019:                new_copy = vm_object_allocate(src_offset + size);
                   2020:                vm_object_lock(new_copy);
                   2021:                goto Retry;
                   2022:        }
                   2023: 
                   2024:        /*
                   2025:         * Readjust the copy-object size if necessary.
                   2026:         */
                   2027:        copy_size = new_copy->size;
                   2028:        if (copy_size < src_offset+size) {
                   2029:                copy_size = src_offset+size;
                   2030:                new_copy->size = copy_size;
                   2031:        }
                   2032: 
                   2033:        /*
                   2034:         *      Point the new copy at the existing object.
                   2035:         */
                   2036: 
                   2037:        new_copy->shadow = src_object;
                   2038:        new_copy->shadow_offset = 0;
                   2039:        new_copy->shadowed = TRUE;      /* caller must set needs_copy */
                   2040:        assert(src_object->ref_count > 0);
                   2041:        src_object->ref_count++;
                   2042:        VM_OBJ_RES_INCR(src_object);
                   2043:        src_object->copy = new_copy;
                   2044:        vm_object_unlock(new_copy);
                   2045: 
                   2046:        /*
                   2047:         *      Mark all (current) pages of the existing object copy-on-write.
                   2048:         *      This object may have a shadow chain below it, but
                   2049:         *      those pages will already be marked copy-on-write.
                   2050:         */
                   2051: 
                   2052:        vm_object_paging_wait(src_object, THREAD_UNINT);
                   2053:        copy_delayed_protect_iterate++;
                   2054:        queue_iterate(&src_object->memq, p, vm_page_t, listq) {
                   2055:            if (!p->fictitious)
                   2056:                pmap_page_protect(p->phys_addr, 
                   2057:                                  (VM_PROT_ALL & ~VM_PROT_WRITE &
                   2058:                                   ~p->page_lock));
                   2059:        }
                   2060:        vm_object_unlock(src_object);
                   2061:        XPR(XPR_VM_OBJECT,
                   2062:                "vm_object_copy_delayed: used copy object %X for source %X\n",
                   2063:                (integer_t)new_copy, (integer_t)src_object, 0, 0, 0);
                   2064: 
                   2065:        return(new_copy);
                   2066: }
                   2067: 
                   2068: /*
                   2069:  *     Routine:        vm_object_copy_strategically
                   2070:  *
                   2071:  *     Purpose:
                   2072:  *             Perform a copy according to the source object's
                   2073:  *             declared strategy.  This operation may block,
                   2074:  *             and may be interrupted.
                   2075:  */
                   2076: kern_return_t
                   2077: vm_object_copy_strategically(
                   2078:        register vm_object_t    src_object,
                   2079:        vm_offset_t             src_offset,
                   2080:        vm_size_t               size,
                   2081:        vm_object_t             *dst_object,    /* OUT */
                   2082:        vm_offset_t             *dst_offset,    /* OUT */
                   2083:        boolean_t               *dst_needs_copy) /* OUT */
                   2084: {
                   2085:        boolean_t       result;
                   2086:        boolean_t       interruptible = THREAD_ABORTSAFE; /* XXX */
                   2087:        memory_object_copy_strategy_t copy_strategy;
                   2088: 
                   2089:        assert(src_object != VM_OBJECT_NULL);
                   2090: 
                   2091:        vm_object_lock(src_object);
                   2092: 
                   2093:        /*
                   2094:         *      The copy strategy is only valid if the memory manager
                   2095:         *      is "ready". Internal objects are always ready.
                   2096:         */
                   2097: 
                   2098:        while (!src_object->internal && !src_object->pager_ready) {
                   2099: 
                   2100:                vm_object_wait( src_object,
                   2101:                                VM_OBJECT_EVENT_PAGER_READY,
                   2102:                                interruptible);
                   2103:                if (interruptible &&
                   2104:                    (current_thread()->wait_result != THREAD_AWAKENED)) {
                   2105:                        *dst_object = VM_OBJECT_NULL;
                   2106:                        *dst_offset = 0;
                   2107:                        *dst_needs_copy = FALSE;
                   2108:                        return(MACH_SEND_INTERRUPTED);
                   2109:                }
                   2110:                vm_object_lock(src_object);
                   2111:        }
                   2112: 
                   2113:        copy_strategy = src_object->copy_strategy;
                   2114: 
                   2115:        /*
                   2116:         *      Use the appropriate copy strategy.
                   2117:         */
                   2118: 
                   2119:        switch (copy_strategy) {
                   2120:            case MEMORY_OBJECT_COPY_NONE:
                   2121:                result = vm_object_copy_slowly(src_object, src_offset, size,
                   2122:                                               interruptible, dst_object);
                   2123:                if (result == KERN_SUCCESS) {
                   2124:                        *dst_offset = 0;
                   2125:                        *dst_needs_copy = FALSE;
                   2126:                }
                   2127:                break;
                   2128: 
                   2129:            case MEMORY_OBJECT_COPY_CALL:
                   2130:                result = vm_object_copy_call(src_object, src_offset, size,
                   2131:                                dst_object);
                   2132:                if (result == KERN_SUCCESS) {
                   2133:                        *dst_offset = src_offset;
                   2134:                        *dst_needs_copy = TRUE;
                   2135:                }
                   2136:                break;
                   2137: 
                   2138:            case MEMORY_OBJECT_COPY_DELAY:
                   2139:                vm_object_unlock(src_object);
                   2140:                *dst_object = vm_object_copy_delayed(src_object,
                   2141:                                                     src_offset, size);
                   2142:                *dst_offset = src_offset;
                   2143:                *dst_needs_copy = TRUE;
                   2144:                result = KERN_SUCCESS;
                   2145:                break;
                   2146: 
                   2147:            case MEMORY_OBJECT_COPY_SYMMETRIC:
                   2148:                XPR(XPR_VM_OBJECT, "v_o_c_strategically obj 0x%x off 0x%x size 0x%x\n",(natural_t)src_object, src_offset, size, 0, 0);
                   2149:                vm_object_unlock(src_object);
                   2150:                result = KERN_MEMORY_RESTART_COPY;
                   2151:                break;
                   2152: 
                   2153:            default:
                   2154:                panic("copy_strategically: bad strategy");
                   2155:                result = KERN_INVALID_ARGUMENT;
                   2156:        }
                   2157:        return(result);
                   2158: }
                   2159: 
                   2160: /*
                   2161:  *     vm_object_shadow:
                   2162:  *
                   2163:  *     Create a new object which is backed by the
                   2164:  *     specified existing object range.  The source
                   2165:  *     object reference is deallocated.
                   2166:  *
                   2167:  *     The new object and offset into that object
                   2168:  *     are returned in the source parameters.
                   2169:  */
                   2170: boolean_t vm_object_shadow_check = FALSE;
                   2171: 
                   2172: boolean_t
                   2173: vm_object_shadow(
                   2174:        vm_object_t     *object,        /* IN/OUT */
                   2175:        vm_offset_t     *offset,        /* IN/OUT */
                   2176:        vm_size_t       length)
                   2177: {
                   2178:        register vm_object_t    source;
                   2179:        register vm_object_t    result;
                   2180: 
                   2181:        source = *object;
                   2182:        assert(source->copy_strategy == MEMORY_OBJECT_COPY_SYMMETRIC);
                   2183: 
                   2184:        /*
                   2185:         *      Determine if we really need a shadow.
                   2186:         */
                   2187: 
                   2188:        if (vm_object_shadow_check && source->ref_count == 1 &&
                   2189:            (source->shadow == VM_OBJECT_NULL ||
                   2190:             source->shadow->copy == VM_OBJECT_NULL))
                   2191:        {
                   2192:                source->shadowed = FALSE;
                   2193:                return FALSE;
                   2194:        }
                   2195: 
                   2196:        /*
                   2197:         *      Allocate a new object with the given length
                   2198:         */
                   2199: 
                   2200:        if ((result = vm_object_allocate(length)) == VM_OBJECT_NULL)
                   2201:                panic("vm_object_shadow: no object for shadowing");
                   2202: 
                   2203:        /*
                   2204:         *      The new object shadows the source object, adding
                   2205:         *      a reference to it.  Our caller changes his reference
                   2206:         *      to point to the new object, removing a reference to
                   2207:         *      the source object.  Net result: no change of reference
                   2208:         *      count.
                   2209:         */
                   2210:        result->shadow = source;
                   2211:        
                   2212:        /*
                   2213:         *      Store the offset into the source object,
                   2214:         *      and fix up the offset into the new object.
                   2215:         */
                   2216: 
                   2217:        result->shadow_offset = *offset;
                   2218: 
                   2219:        /*
                   2220:         *      Return the new things
                   2221:         */
                   2222: 
                   2223:        *offset = 0;
                   2224:        *object = result;
                   2225:        return TRUE;
                   2226: }
                   2227: 
                   2228: /*
                   2229:  *     The relationship between vm_object structures and
                   2230:  *     the memory_object ports requires careful synchronization.
                   2231:  *
                   2232:  *     All associations are created by vm_object_enter.  All three
                   2233:  *     port fields are filled in, as follows:
                   2234:  *             pager:  the memory_object port itself, supplied by
                   2235:  *                     the user requesting a mapping (or the kernel,
                   2236:  *                     when initializing internal objects); the
                   2237:  *                     kernel simulates holding send rights by keeping
                   2238:  *                     a port reference;
                   2239:  *             pager_request:
                   2240:  *                     the memory object control port,
                   2241:  *                     created by the kernel; the kernel holds
                   2242:  *                     receive (and ownership) rights to this
                   2243:  *                     port, but no other references.
                   2244:  *     All of the ports are referenced by their global names.
                   2245:  *
                   2246:  *     When initialization is complete, the "initialized" field
                   2247:  *     is asserted.  Other mappings using a particular memory object,
                   2248:  *     and any references to the vm_object gained through the
                   2249:  *     port association must wait for this initialization to occur.
                   2250:  *
                   2251:  *     In order to allow the memory manager to set attributes before
                   2252:  *     requests (notably virtual copy operations, but also data or
                   2253:  *     unlock requests) are made, a "ready" attribute is made available.
                   2254:  *     Only the memory manager may affect the value of this attribute.
                   2255:  *     Its value does not affect critical kernel functions, such as
                   2256:  *     internal object initialization or destruction.  [Furthermore,
                   2257:  *     memory objects created by the kernel are assumed to be ready
                   2258:  *     immediately; the default memory manager need not explicitly
                   2259:  *     set the "ready" attribute.]
                   2260:  *
                   2261:  *     [Both the "initialized" and "ready" attribute wait conditions
                   2262:  *     use the "pager" field as the wait event.]
                   2263:  *
                   2264:  *     The port associations can be broken down by any of the
                   2265:  *     following routines:
                   2266:  *             vm_object_terminate:
                   2267:  *                     No references to the vm_object remain, and
                   2268:  *                     the object cannot (or will not) be cached.
                   2269:  *                     This is the normal case, and is done even
                   2270:  *                     though one of the other cases has already been
                   2271:  *                     done.
                   2272:  *             vm_object_destroy:
                   2273:  *                     The memory_object port has been destroyed,
                   2274:  *                     meaning that the kernel cannot flush dirty
                   2275:  *                     pages or request new data or unlock existing
                   2276:  *                     data.
                   2277:  *             memory_object_destroy:
                   2278:  *                     The memory manager has requested that the
                   2279:  *                     kernel relinquish rights to the memory object
                   2280:  *                     port.  [The memory manager may not want to
                   2281:  *                     destroy the port, but may wish to refuse or
                   2282:  *                     tear down existing memory mappings.]
                   2283:  *     Each routine that breaks an association must break all of
                   2284:  *     them at once.  At some later time, that routine must clear
                   2285:  *     the vm_object port fields and release the port rights.
                   2286:  *     [Furthermore, each routine must cope with the simultaneous
                   2287:  *     or previous operations of the others.]
                   2288:  *
                   2289:  *     In addition to the lock on the object, the vm_object_cache_lock
                   2290:  *     governs the port associations.  References gained through the
                   2291:  *     port association require use of the cache lock.
                   2292:  *
                   2293:  *     Because the port fields may be cleared spontaneously, they
                   2294:  *     cannot be used to determine whether a memory object has
                   2295:  *     ever been associated with a particular vm_object.  [This
                   2296:  *     knowledge is important to the shadow object mechanism.]
                   2297:  *     For this reason, an additional "created" attribute is
                   2298:  *     provided.
                   2299:  *
                   2300:  *     During various paging operations, the port values found in the
                   2301:  *     vm_object must be valid.  To prevent these port rights from being
                   2302:  *     released, and to prevent the port associations from changing
                   2303:  *     (other than being removed, i.e., made null), routines may use
                   2304:  *     the vm_object_paging_begin/end routines [actually, macros].
                   2305:  *     The implementation uses the "paging_in_progress" and "wanted" fields.
                   2306:  *     [Operations that alter the validity of the port values include the
                   2307:  *     termination routines and vm_object_collapse.]
                   2308:  */
                   2309: 
                   2310: #define        IKOT_PAGER_LOOKUP_TYPE  IKOT_PAGING_REQUEST
                   2311: 
                   2312: vm_object_t
                   2313: vm_object_lookup(
                   2314:        ipc_port_t      port)
                   2315: {
                   2316:        vm_object_t     object;
                   2317: 
                   2318: start_over:
                   2319:        object = VM_OBJECT_NULL;
                   2320: 
                   2321:        if (IP_VALID(port)) {
                   2322:                vm_object_cache_lock();
                   2323:                ip_lock(port);
                   2324:                if (ip_active(port) &&
                   2325:                    (ip_kotype(port) == IKOT_PAGER_LOOKUP_TYPE)) {
                   2326:                        object = (vm_object_t) port->ip_kobject;
                   2327:                        if (!vm_object_lock_try(object)) {
                   2328:                                /*
                   2329:                                 * failed to acquire object lock.  Drop the
                   2330:                                 * other two locks and wait for it, then go
                   2331:                                 * back and start over in case the port
                   2332:                                 * associations changed in the interim.
                   2333:                                 */
                   2334:                                ip_unlock(port);
                   2335:                                vm_object_cache_unlock();
                   2336:                                vm_object_lock(object);
                   2337:                                vm_object_unlock(object);
                   2338:                                goto start_over;
                   2339:                        }
                   2340: 
                   2341:                        assert(object->alive);
                   2342: 
                   2343:                        if (object->ref_count == 0) {
                   2344:                                queue_remove(&vm_object_cached_list, object,
                   2345:                                             vm_object_t, cached_list);
                   2346:                                vm_object_cached_count--;
                   2347:                                XPR(XPR_VM_OBJECT_CACHE,
                   2348:                               "vm_object_lookup: removing %X, head (%X, %X)\n",
                   2349:                                    (integer_t)object, 
                   2350:                                    (integer_t)vm_object_cached_list.next,
                   2351:                                    (integer_t)vm_object_cached_list.prev, 0,0);
                   2352:                        }
                   2353: 
                   2354:                        object->ref_count++;
                   2355:                        vm_object_res_reference(object);
                   2356:                        vm_object_unlock(object);
                   2357:                }
                   2358:                ip_unlock(port);
                   2359:                vm_object_cache_unlock();
                   2360:        }
                   2361: 
                   2362:        return object;
                   2363: }
                   2364: 
                   2365: 
                   2366: 
                   2367: void
                   2368: vm_object_destroy(
                   2369:        ipc_port_t      pager)
                   2370: {
                   2371:        vm_object_t             object;
                   2372:        vm_object_hash_entry_t  entry;
                   2373:        pager_request_t         old_pager_request;
                   2374: 
                   2375:        /*
                   2376:         *      Perform essentially the same operations as in vm_object_lookup,
                   2377:         *      except that this time we look up based on the memory_object
                   2378:         *      port, not the control port.
                   2379:         */
                   2380:        vm_object_cache_lock();
                   2381:        entry = vm_object_hash_lookup(pager, FALSE);
                   2382:        if (entry == VM_OBJECT_HASH_ENTRY_NULL ||
                   2383:                        entry->object == VM_OBJECT_NULL) {
                   2384:                vm_object_cache_unlock();
                   2385:                return;
                   2386:        }
                   2387: 
                   2388:        object = entry->object;
                   2389:        entry->object = VM_OBJECT_NULL;
                   2390: 
                   2391:        vm_object_lock(object);
                   2392:        if (object->ref_count == 0) {
                   2393:                XPR(XPR_VM_OBJECT_CACHE,
                   2394:                   "vm_object_destroy: removing %x from cache, head (%x, %x)\n",
                   2395:                        (integer_t)object,
                   2396:                        (integer_t)vm_object_cached_list.next,
                   2397:                        (integer_t)vm_object_cached_list.prev, 0,0);
                   2398: 
                   2399:                queue_remove(&vm_object_cached_list, object,
                   2400:                                vm_object_t, cached_list);
                   2401:                vm_object_cached_count--;
                   2402:        }
                   2403:        object->ref_count++;
                   2404:        vm_object_res_reference(object);
                   2405: 
                   2406:        object->can_persist = FALSE;
                   2407: 
                   2408:        assert(object->pager == pager);
                   2409: 
                   2410:        /*
                   2411:         *      Remove the port associations.
                   2412:         *
                   2413:         *      Note that the memory_object itself is dead, so
                   2414:         *      we don't bother with it.
                   2415:         */
                   2416: 
                   2417:        object->pager = IP_NULL;
                   2418:        vm_object_remove(object);
                   2419: 
                   2420:        old_pager_request = object->pager_request;
                   2421: 
                   2422:        object->pager_request = PAGER_REQUEST_NULL;
                   2423: 
                   2424:        vm_object_unlock(object);
                   2425:        vm_object_cache_unlock();
                   2426: 
                   2427:        vm_object_pager_wakeup(pager);
                   2428: 
                   2429:        /*
                   2430:         *      Clean up the port references.  Note that there's no
                   2431:         *      point in trying the memory_object_terminate call
                   2432:         *      because the memory_object itself is dead.
                   2433:         */
                   2434: 
                   2435:        ipc_port_release_send(pager);
                   2436: 
                   2437:        if ((ipc_port_t)old_pager_request != IP_NULL)
                   2438:                ipc_port_dealloc_kernel((ipc_port_t)old_pager_request);
                   2439: 
                   2440:        /*
                   2441:         *      Restart pending page requests
                   2442:         */
                   2443:        vm_object_lock(object);
                   2444: 
                   2445:        vm_object_abort_activity(object);
                   2446: 
                   2447:        vm_object_unlock(object);
                   2448: 
                   2449:        /*
                   2450:         *      Lose the object reference.
                   2451:         */
                   2452: 
                   2453:        vm_object_deallocate(object);
                   2454: }
                   2455: 
                   2456: /*
                   2457:  *     Routine:        vm_object_enter
                   2458:  *     Purpose:
                   2459:  *             Find a VM object corresponding to the given
                   2460:  *             pager; if no such object exists, create one,
                   2461:  *             and initialize the pager.
                   2462:  */
                   2463: vm_object_t
                   2464: vm_object_enter(
                   2465:        ipc_port_t              pager,
                   2466:        vm_size_t               size,
                   2467:        boolean_t               internal,
                   2468:        boolean_t               init)
                   2469: {
                   2470:        register vm_object_t    object;
                   2471:        vm_object_t             new_object;
                   2472:        boolean_t               must_init;
                   2473:        ipc_port_t              pager_request;
                   2474:        vm_object_hash_entry_t  entry, new_entry;
                   2475: #ifdef MACH_BSD
                   2476: kern_return_t   vnode_pager_init( ipc_port_t, ipc_port_t, vm_size_t);
                   2477: #endif
                   2478: 
                   2479:        if (!IP_VALID(pager))
                   2480:                return(vm_object_allocate(size));
                   2481: 
                   2482:        new_object = VM_OBJECT_NULL;
                   2483:        new_entry = VM_OBJECT_HASH_ENTRY_NULL;
                   2484:        must_init = init;
                   2485: 
                   2486:        /*
                   2487:         *      Look for an object associated with this port.
                   2488:         */
                   2489: 
                   2490: restart:
                   2491:        vm_object_cache_lock();
                   2492:        for (;;) {
                   2493:                entry = vm_object_hash_lookup(pager, FALSE);
                   2494: 
                   2495:                /*
                   2496:                 *      If a previous object is being terminated,
                   2497:                 *      we must wait for the termination message
                   2498:                 *      to be queued.
                   2499:                 *
                   2500:                 *      We set kobject to a non-null value to let the
                   2501:                 *      terminator know that someone is waiting.
                   2502:                 *      Among the possibilities is that the port
                   2503:                 *      could die while we're waiting.  Must restart
                   2504:                 *      instead of continuing the loop.
                   2505:                 */
                   2506: 
                   2507:                if (entry != VM_OBJECT_HASH_ENTRY_NULL) {
                   2508:                        if (entry->object != VM_OBJECT_NULL)
                   2509:                                break;
                   2510: 
                   2511:                        entry->waiting = TRUE;
                   2512:                        assert_wait((event_t) pager, THREAD_UNINT);
                   2513:                        vm_object_cache_unlock();
                   2514:                        thread_block((void (*)(void))0);
                   2515:                        goto restart;
                   2516:                }
                   2517: 
                   2518:                /*
                   2519:                 *      We must unlock to create a new object;
                   2520:                 *      if we do so, we must try the lookup again.
                   2521:                 */
                   2522: 
                   2523:                if (new_object == VM_OBJECT_NULL) {
                   2524:                        vm_object_cache_unlock();
                   2525:                        assert(new_entry == VM_OBJECT_HASH_ENTRY_NULL);
                   2526:                        new_entry = vm_object_hash_entry_alloc(pager);
                   2527:                        new_object = vm_object_allocate(size);
                   2528:                        vm_object_cache_lock();
                   2529:                } else {
                   2530:                        /*
                   2531:                         *      Lookup failed twice, and we have something
                   2532:                         *      to insert; set the object.
                   2533:                         */
                   2534: 
                   2535:                        if (entry == VM_OBJECT_HASH_ENTRY_NULL) {
                   2536:                                vm_object_hash_insert(new_entry);
                   2537:                                entry = new_entry;
                   2538:                                new_entry = VM_OBJECT_HASH_ENTRY_NULL;
                   2539:                        }
                   2540: 
                   2541:                        entry->object = new_object;
                   2542:                        new_object = VM_OBJECT_NULL;
                   2543:                        must_init = TRUE;
                   2544:                }
                   2545:        }
                   2546: 
                   2547:        object = entry->object;
                   2548:        assert(object != VM_OBJECT_NULL);
                   2549: 
                   2550:        if (!must_init) {
                   2551:                vm_object_lock(object);
                   2552:                assert(object->pager_created);
                   2553:                assert(!internal || object->internal);
                   2554:                if (object->ref_count == 0) {
                   2555:                        XPR(XPR_VM_OBJECT_CACHE,
                   2556:                    "vm_object_enter: removing %x from cache, head (%x, %x)\n",
                   2557:                                (integer_t)object,
                   2558:                                (integer_t)vm_object_cached_list.next,
                   2559:                                (integer_t)vm_object_cached_list.prev, 0,0);
                   2560:                        queue_remove(&vm_object_cached_list, object,
                   2561:                                     vm_object_t, cached_list);
                   2562:                        vm_object_cached_count--;
                   2563:                }
                   2564:                object->ref_count++;
                   2565:                vm_object_res_reference(object);
                   2566:                vm_object_unlock(object);
                   2567: 
                   2568:                VM_STAT(hits++);
                   2569:        } 
                   2570:        assert(object->ref_count > 0);
                   2571: 
                   2572:        VM_STAT(lookups++);
                   2573: 
                   2574:        vm_object_cache_unlock();
                   2575: 
                   2576:        XPR(XPR_VM_OBJECT,
                   2577:                "vm_o_enter: pager 0x%x obj 0x%x must_init %d\n",
                   2578:                (integer_t)pager, (integer_t)object, must_init, 0, 0);
                   2579: 
                   2580:        /*
                   2581:         *      If we raced to create a vm_object but lost, let's
                   2582:         *      throw away ours.
                   2583:         */
                   2584: 
                   2585:        if (new_object != VM_OBJECT_NULL)
                   2586:                vm_object_deallocate(new_object);
                   2587: 
                   2588:        if (new_entry != VM_OBJECT_HASH_ENTRY_NULL)
                   2589:                vm_object_hash_entry_free(new_entry);
                   2590: 
                   2591:        if (must_init) {
                   2592: 
                   2593:                /*
                   2594:                 *      Allocate request port.
                   2595:                 */
                   2596: 
                   2597:                pager_request = ipc_port_alloc_kernel();
                   2598:                assert (pager_request != IP_NULL);
                   2599:                ipc_kobject_set(pager_request, (ipc_kobject_t) object,
                   2600:                                IKOT_PAGING_REQUEST);
                   2601: 
                   2602:                vm_object_lock(object);
                   2603: 
                   2604:                /*
                   2605:                 *      Copy the naked send right we were given.
                   2606:                 */
                   2607: 
                   2608:                pager = ipc_port_copy_send(pager);
                   2609:                if (!IP_VALID(pager))
                   2610:                        panic("vm_object_enter: port died"); /* XXX */
                   2611: 
                   2612:                object->pager_created = TRUE;
                   2613:                object->pager = pager;
                   2614:                object->internal = internal;
                   2615:                object->pager_trusted = internal;
                   2616:                if (!internal) {
                   2617:                        /* copy strategy invalid until set by memory manager */
                   2618:                        object->copy_strategy = MEMORY_OBJECT_COPY_INVALID;
                   2619:                }
                   2620:                object->pager_request = pager_request;
                   2621:                object->pager_ready = FALSE;
                   2622: 
                   2623:                vm_object_unlock(object);
                   2624: 
                   2625:                /*
                   2626:                 *      Let the pager know we're using it.
                   2627:                 */
                   2628: 
                   2629: #ifdef MACH_BSD
                   2630:                if(((rpc_subsystem_t)pager_mux_hash_lookup(pager)) == 
                   2631:                        ((rpc_subsystem_t) &vnode_pager_workaround)) {
                   2632:                        (void) vnode_pager_init(pager,
                   2633:                                object->pager_request,
                   2634:                                PAGE_SIZE);
                   2635:                } else {
                   2636:                        (void) memory_object_init(pager,
                   2637:                                object->pager_request,
                   2638:                                PAGE_SIZE);
                   2639:                }
                   2640: #else
                   2641:                        (void) memory_object_init(pager,
                   2642:                                object->pager_request,
                   2643:                                PAGE_SIZE);
                   2644: #endif
                   2645: 
                   2646:                vm_object_lock(object);
                   2647:                if (internal) {
                   2648:                        object->pager_ready = TRUE;
                   2649:                        vm_object_wakeup(object, VM_OBJECT_EVENT_PAGER_READY);
                   2650:                }
                   2651: 
                   2652:                object->pager_initialized = TRUE;
                   2653:                vm_object_wakeup(object, VM_OBJECT_EVENT_INITIALIZED);
                   2654:        } else {
                   2655:                vm_object_lock(object);
                   2656:        }
                   2657: 
                   2658:        /*
                   2659:         *      [At this point, the object must be locked]
                   2660:         */
                   2661: 
                   2662:        /*
                   2663:         *      Wait for the work above to be done by the first
                   2664:         *      thread to map this object.
                   2665:         */
                   2666: 
                   2667:        while (!object->pager_initialized) {
                   2668:                vm_object_wait( object,
                   2669:                                VM_OBJECT_EVENT_INITIALIZED,
                   2670:                                THREAD_UNINT);
                   2671:                vm_object_lock(object);
                   2672:        }
                   2673:        vm_object_unlock(object);
                   2674: 
                   2675:        XPR(XPR_VM_OBJECT,
                   2676:            "vm_object_enter: vm_object %x, memory_object %x, internal %d\n",
                   2677:            (integer_t)object, (integer_t)object->pager, internal, 0,0);
                   2678:        return(object);
                   2679: }
                   2680: 
                   2681: /*
                   2682:  *     Routine:        vm_object_pager_create
                   2683:  *     Purpose:
                   2684:  *             Create a memory object for an internal object.
                   2685:  *     In/out conditions:
                   2686:  *             The object is locked on entry and exit;
                   2687:  *             it may be unlocked within this call.
                   2688:  *     Limitations:
                   2689:  *             Only one thread may be performing a
                   2690:  *             vm_object_pager_create on an object at
                   2691:  *             a time.  Presumably, only the pageout
                   2692:  *             daemon will be using this routine.
                   2693:  */
                   2694: 
                   2695: void
                   2696: vm_object_pager_create(
                   2697:        register vm_object_t    object)
                   2698: {
                   2699:        ipc_port_t              pager;
                   2700:        vm_object_hash_entry_t  entry;
                   2701: #if    MACH_PAGEMAP
                   2702:        vm_size_t               size;
                   2703:        vm_external_map_t       map;
                   2704: #endif /* MACH_PAGEMAP */
                   2705: 
                   2706:        XPR(XPR_VM_OBJECT, "vm_object_pager_create, object 0x%X\n",
                   2707:                (integer_t)object, 0,0,0,0);
                   2708: 
                   2709:        if (memory_manager_default_check() != KERN_SUCCESS)
                   2710:                return;
                   2711: 
                   2712:        /*
                   2713:         *      Prevent collapse or termination by holding a paging reference
                   2714:         */
                   2715: 
                   2716:        vm_object_paging_begin(object);
                   2717:        if (object->pager_created) {
                   2718:                /*
                   2719:                 *      Someone else got to it first...
                   2720:                 *      wait for them to finish initializing the ports
                   2721:                 */
                   2722:                while (!object->pager_initialized) {
                   2723:                        vm_object_wait( object,
                   2724:                                       VM_OBJECT_EVENT_INITIALIZED,
                   2725:                                       THREAD_UNINT);
                   2726:                        vm_object_lock(object);
                   2727:                }
                   2728:                vm_object_paging_end(object);
                   2729:                return;
                   2730:        }
                   2731: 
                   2732:        /*
                   2733:         *      Indicate that a memory object has been assigned
                   2734:         *      before dropping the lock, to prevent a race.
                   2735:         */
                   2736: 
                   2737:        object->pager_created = TRUE;
                   2738:        object->paging_offset = 0;
                   2739:                
                   2740: #if    MACH_PAGEMAP
                   2741:        size = object->size;
                   2742: #endif /* MACH_PAGEMAP */
                   2743:        vm_object_unlock(object);
                   2744: 
                   2745: #if    MACH_PAGEMAP
                   2746:        map = vm_external_create(size);
                   2747:        vm_object_lock(object);
                   2748:        assert(object->size == size);
                   2749:        object->existence_map = map;
                   2750:        vm_object_unlock(object);
                   2751: #endif /* MACH_PAGEMAP */
                   2752: 
                   2753:        /*
                   2754:         *      Create the pager ports, and associate them with this object.
                   2755:         *
                   2756:         *      We make the port association here so that vm_object_enter()
                   2757:         *      can look up the object to complete initializing it.  No
                   2758:         *      user will ever map this object.
                   2759:         */
                   2760:        {
                   2761:                ipc_port_t      DMM;
                   2762:                vm_size_t       cluster_size;
                   2763: 
                   2764:                /* acquire a naked send right for the DMM */
                   2765:                DMM = memory_manager_default_reference(&cluster_size);
                   2766:                assert(cluster_size >= PAGE_SIZE);
                   2767: 
                   2768:                object->cluster_size = cluster_size; /* XXX ??? */
                   2769:                assert(object->temporary);
                   2770: 
                   2771:                /* consumes the naked send right for DMM */
                   2772:                (void) memory_object_create(DMM, &pager, object->size);
                   2773:                assert(IP_VALID(pager));
                   2774:        }
                   2775: 
                   2776:        entry = vm_object_hash_entry_alloc(pager);
                   2777: 
                   2778:        vm_object_cache_lock();
                   2779:        vm_object_hash_insert(entry);
                   2780: 
                   2781:        entry->object = object;
                   2782:        vm_object_cache_unlock();
                   2783: 
                   2784:        /*
                   2785:         *      A naked send right was returned by
                   2786:         *      memory_object_create(), and it is
                   2787:         *      copied by vm_object_enter().
                   2788:         */
                   2789: 
                   2790:        if (vm_object_enter(pager, object->size, TRUE, TRUE) != object)
                   2791:                panic("vm_object_pager_create: mismatch");
                   2792: 
                   2793:        /*
                   2794:         *      Drop the naked send right.
                   2795:         */
                   2796:        ipc_port_release_send(pager);
                   2797: 
                   2798:        vm_object_lock(object);
                   2799: 
                   2800:        /*
                   2801:         *      Release the paging reference
                   2802:         */
                   2803:        vm_object_paging_end(object);
                   2804: }
                   2805: 
                   2806: /*
                   2807:  *     Routine:        vm_object_remove
                   2808:  *     Purpose:
                   2809:  *             Eliminate the pager/object association
                   2810:  *             for this pager.
                   2811:  *     Conditions:
                   2812:  *             The object cache must be locked.
                   2813:  */
                   2814: void
                   2815: vm_object_remove(
                   2816:        vm_object_t     object)
                   2817: {
                   2818:        ipc_port_t port;
                   2819: 
                   2820:        if ((port = object->pager) != IP_NULL) {
                   2821:                vm_object_hash_entry_t  entry;
                   2822: 
                   2823:                entry = vm_object_hash_lookup(port, FALSE);
                   2824:                if (entry != VM_OBJECT_HASH_ENTRY_NULL)
                   2825:                        entry->object = VM_OBJECT_NULL;
                   2826:        }
                   2827: 
                   2828:        if ((port = object->pager_request) != IP_NULL) {
                   2829:                if (ip_kotype(port) == IKOT_PAGING_REQUEST)
                   2830:                        ipc_kobject_set(port, IKO_NULL, IKOT_NONE);
                   2831:                 else if (ip_kotype(port) != IKOT_NONE)
                   2832:                        panic("vm_object_remove: bad request port");
                   2833:        }
                   2834: }
                   2835: 
                   2836: /*
                   2837:  *     Global variables for vm_object_collapse():
                   2838:  *
                   2839:  *             Counts for normal collapses and bypasses.
                   2840:  *             Debugging variables, to watch or disable collapse.
                   2841:  */
                   2842: long   object_collapses = 0;
                   2843: long   object_bypasses  = 0;
                   2844: 
                   2845: boolean_t      vm_object_collapse_allowed = TRUE;
                   2846: boolean_t      vm_object_bypass_allowed = TRUE;
                   2847: 
                   2848: int    vm_external_discarded;
                   2849: int    vm_external_collapsed;
                   2850: /*
                   2851:  *     vm_object_do_collapse:
                   2852:  *
                   2853:  *     Collapse an object with the object backing it.
                   2854:  *     Pages in the backing object are moved into the
                   2855:  *     parent, and the backing object is deallocated.
                   2856:  *
                   2857:  *     Both objects and the cache are locked; the page
                   2858:  *     queues are unlocked.
                   2859:  *
                   2860:  */
                   2861: void
                   2862: vm_object_do_collapse(
                   2863:        vm_object_t object,
                   2864:        vm_object_t backing_object)
                   2865: {
                   2866:        vm_page_t p, pp;
                   2867:        vm_offset_t new_offset, backing_offset;
                   2868:        vm_size_t size;
                   2869: 
                   2870:        backing_offset = object->shadow_offset;
                   2871:        size = object->size;
                   2872: 
                   2873: 
                   2874:        /*
                   2875:         *      Move all in-memory pages from backing_object
                   2876:         *      to the parent.  Pages that have been paged out
                   2877:         *      will be overwritten by any of the parent's
                   2878:         *      pages that shadow them.
                   2879:         */
                   2880:        
                   2881:        while (!queue_empty(&backing_object->memq)) {
                   2882:                
                   2883:                p = (vm_page_t) queue_first(&backing_object->memq);
                   2884:                
                   2885:                new_offset = (p->offset - backing_offset);
                   2886:                
                   2887:                assert(!p->busy || p->absent);
                   2888:                
                   2889:                /*
                   2890:                 *      If the parent has a page here, or if
                   2891:                 *      this page falls outside the parent,
                   2892:                 *      dispose of it.
                   2893:                 *
                   2894:                 *      Otherwise, move it as planned.
                   2895:                 */
                   2896:                
                   2897:                if (p->offset < backing_offset || new_offset >= size) {
                   2898:                        VM_PAGE_FREE(p);
                   2899:                } else {
                   2900:                        pp = vm_page_lookup(object, new_offset);
                   2901:                        if (pp == VM_PAGE_NULL) {
                   2902: 
                   2903:                                /*
                   2904:                                 *      Parent now has no page.
                   2905:                                 *      Move the backing object's page up.
                   2906:                                 */
                   2907: 
                   2908:                                vm_page_rename(p, object, new_offset);
                   2909: #if    MACH_PAGEMAP
                   2910:                        } else if (pp->absent) {
                   2911: 
                   2912:                                /*
                   2913:                                 *      Parent has an absent page...
                   2914:                                 *      it's not being paged in, so
                   2915:                                 *      it must really be missing from
                   2916:                                 *      the parent.
                   2917:                                 *
                   2918:                                 *      Throw out the absent page...
                   2919:                                 *      any faults looking for that
                   2920:                                 *      page will restart with the new
                   2921:                                 *      one.
                   2922:                                 */
                   2923: 
                   2924:                                VM_PAGE_FREE(pp);
                   2925:                                vm_page_rename(p, object, new_offset);
                   2926: #endif /* MACH_PAGEMAP */
                   2927:                        } else {
                   2928:                                assert(! pp->absent);
                   2929: 
                   2930:                                /*
                   2931:                                 *      Parent object has a real page.
                   2932:                                 *      Throw away the backing object's
                   2933:                                 *      page.
                   2934:                                 */
                   2935:                                VM_PAGE_FREE(p);
                   2936:                        }
                   2937:                }
                   2938:        }
                   2939:        
                   2940:        assert(object->pager == IP_NULL || backing_object->pager == IP_NULL);
                   2941: 
                   2942:        if (backing_object->pager != IP_NULL) {
                   2943:                vm_object_hash_entry_t  entry;
                   2944: 
                   2945:                /*
                   2946:                 *      Move the pager from backing_object to object.
                   2947:                 *
                   2948:                 *      XXX We're only using part of the paging space
                   2949:                 *      for keeps now... we ought to discard the
                   2950:                 *      unused portion.
                   2951:                 */
                   2952: 
                   2953:                object->pager = backing_object->pager;
                   2954:                entry = vm_object_hash_lookup(object->pager, FALSE);
                   2955:                assert(entry != VM_OBJECT_HASH_ENTRY_NULL);
                   2956:                entry->object = object;
                   2957:                object->pager_created = backing_object->pager_created;
                   2958:                object->pager_request = backing_object->pager_request;
                   2959:                object->pager_ready = backing_object->pager_ready;
                   2960:                object->pager_initialized = backing_object->pager_initialized;
                   2961:                object->cluster_size = backing_object->cluster_size;
                   2962:                object->paging_offset =
                   2963:                    backing_object->paging_offset + backing_offset;
                   2964:                if (object->pager_request != IP_NULL) {
                   2965:                        ipc_kobject_set(object->pager_request,
                   2966:                                        (ipc_kobject_t) object,
                   2967:                                        IKOT_PAGING_REQUEST);
                   2968:                }
                   2969:        }
                   2970: 
                   2971:        vm_object_cache_unlock();
                   2972: 
                   2973:        object->paging_offset = backing_object->paging_offset + backing_offset;
                   2974: 
                   2975: #if    MACH_PAGEMAP
                   2976:        /*
                   2977:         *      If the shadow offset is 0, the use the existence map from
                   2978:         *      the backing object if there is one. If the shadow offset is
                   2979:         *      not zero, toss it.
                   2980:         *
                   2981:         *      XXX - If the shadow offset is not 0 then a bit copy is needed
                   2982:         *      if the map is to be salvaged.  For now, we just just toss the
                   2983:         *      old map, giving the collapsed object no map. This means that
                   2984:         *      the pager is invoked for zero fill pages.  If analysis shows
                   2985:         *      that this happens frequently and is a performance hit, then
                   2986:         *      this code should be fixed to salvage the map.
                   2987:         */
                   2988:        assert(object->existence_map == VM_EXTERNAL_NULL);
                   2989:        if (backing_offset || (size != backing_object->size)) {
                   2990:                vm_external_discarded++;
                   2991:                vm_external_destroy(backing_object->existence_map,
                   2992:                        backing_object->size);
                   2993:        }
                   2994:        else {
                   2995:                vm_external_collapsed++;
                   2996:                object->existence_map = backing_object->existence_map;
                   2997:        }
                   2998:        backing_object->existence_map = VM_EXTERNAL_NULL;
                   2999: #endif /* MACH_PAGEMAP */
                   3000: 
                   3001:        /*
                   3002:         *      Object now shadows whatever backing_object did.
                   3003:         *      Note that the reference to backing_object->shadow
                   3004:         *      moves from within backing_object to within object.
                   3005:         */
                   3006:        
                   3007:        object->shadow = backing_object->shadow;
                   3008:        object->shadow_offset += backing_object->shadow_offset;
                   3009:        assert((object->shadow == VM_OBJECT_NULL) ||
                   3010:               (object->shadow->copy == VM_OBJECT_NULL));
                   3011: 
                   3012:        /*
                   3013:         *      Discard backing_object.
                   3014:         *
                   3015:         *      Since the backing object has no pages, no
                   3016:         *      pager left, and no object references within it,
                   3017:         *      all that is necessary is to dispose of it.
                   3018:         */
                   3019:        
                   3020:        assert((backing_object->ref_count == 1) &&
                   3021:               (backing_object->resident_page_count == 0) &&
                   3022:               (backing_object->paging_in_progress == 0));
                   3023: 
                   3024:        assert(backing_object->alive);
                   3025:        backing_object->alive = FALSE;
                   3026:        vm_object_unlock(backing_object);
                   3027: 
                   3028:        XPR(XPR_VM_OBJECT, "vm_object_collapse, collapsed 0x%X\n",
                   3029:                (integer_t)backing_object, 0,0,0,0);
                   3030: 
                   3031:        zfree(vm_object_zone, (vm_offset_t) backing_object);
                   3032:        
                   3033:        object_collapses++;
                   3034: }
                   3035: 
                   3036: void
                   3037: vm_object_do_bypass(
                   3038:        vm_object_t object,
                   3039:        vm_object_t backing_object)
                   3040: {
                   3041:        /*
                   3042:         *      Make the parent shadow the next object
                   3043:         *      in the chain.
                   3044:         */
                   3045:        
                   3046: #if    TASK_SWAPPER
                   3047:        /*
                   3048:         *      Do object reference in-line to 
                   3049:         *      conditionally increment shadow's
                   3050:         *      residence count.  If object is not
                   3051:         *      resident, leave residence count
                   3052:         *      on shadow alone.
                   3053:         */
                   3054:        if (backing_object->shadow != VM_OBJECT_NULL) {
                   3055:                vm_object_lock(backing_object->shadow);
                   3056:                backing_object->shadow->ref_count++;
                   3057:                if (object->res_count != 0)
                   3058:                        vm_object_res_reference(backing_object->shadow);
                   3059:                vm_object_unlock(backing_object->shadow);
                   3060:        }
                   3061: #else  /* TASK_SWAPPER */
                   3062:        vm_object_reference(backing_object->shadow);
                   3063: #endif /* TASK_SWAPPER */
                   3064: 
                   3065:        object->shadow = backing_object->shadow;
                   3066:        object->shadow_offset += backing_object->shadow_offset;
                   3067:        
                   3068:        /*
                   3069:         *      Backing object might have had a copy pointer
                   3070:         *      to us.  If it did, clear it. 
                   3071:         */
                   3072:        if (backing_object->copy == object) {
                   3073:                backing_object->copy = VM_OBJECT_NULL;
                   3074:        }
                   3075:        
                   3076:        /*
                   3077:         *      Drop the reference count on backing_object.
                   3078: #if    TASK_SWAPPER
                   3079:         *      Since its ref_count was at least 2, it
                   3080:         *      will not vanish; so we don't need to call
                   3081:         *      vm_object_deallocate.
                   3082:         *      [FBDP: that doesn't seem to be true any more]
                   3083:         * 
                   3084:         *      The res_count on the backing object is
                   3085:         *      conditionally decremented.  It's possible
                   3086:         *      (via vm_pageout_scan) to get here with
                   3087:         *      a "swapped" object, which has a 0 res_count,
                   3088:         *      in which case, the backing object res_count
                   3089:         *      is already down by one.
                   3090: #else
                   3091:         *      Don't call vm_object_deallocate unless
                   3092:         *      ref_count drops to zero.
                   3093:         *
                   3094:         *      The ref_count can drop to zero here if the
                   3095:         *      backing object could be bypassed but not
                   3096:         *      collapsed, such as when the backing object
                   3097:         *      is temporary and cachable.
                   3098: #endif
                   3099:         */
                   3100:        if (backing_object->ref_count > 1) {
                   3101:                backing_object->ref_count--;
                   3102: #if    TASK_SWAPPER
                   3103:                if (object->res_count != 0)
                   3104:                        vm_object_res_deallocate(backing_object);
                   3105:                assert(backing_object->ref_count > 0);
                   3106: #endif /* TASK_SWAPPER */
                   3107:                vm_object_unlock(backing_object);
                   3108:        } else {
                   3109: 
                   3110:                /*
                   3111:                 *      Drop locks so that we can deallocate
                   3112:                 *      the backing object.
                   3113:                 */
                   3114: 
                   3115: #if    TASK_SWAPPER
                   3116:                if (object->res_count == 0) {
                   3117:                        /* XXX get a reference for the deallocate below */
                   3118:                        vm_object_res_reference(backing_object);
                   3119:                }
                   3120: #endif /* TASK_SWAPPER */
                   3121:                vm_object_unlock(object);
                   3122:                vm_object_unlock(backing_object);
                   3123:                vm_object_deallocate(backing_object);
                   3124: 
                   3125:                /*
                   3126:                 *      Relock object. We don't have to reverify
                   3127:                 *      its state since vm_object_collapse will
                   3128:                 *      do that for us as it starts at the
                   3129:                 *      top of its loop.
                   3130:                 */
                   3131: 
                   3132:                vm_object_lock(object);
                   3133:        }
                   3134:        
                   3135:        object_bypasses++;
                   3136: }
                   3137:                
                   3138: /*
                   3139:  *     vm_object_collapse:
                   3140:  *
                   3141:  *     Perform an object collapse or an object bypass if appropriate.
                   3142:  *     The real work of collapsing and bypassing is performed in
                   3143:  *     the routines vm_object_do_collapse and vm_object_do_bypass.
                   3144:  *
                   3145:  *     Requires that the object be locked and the page queues be unlocked.
                   3146:  *
                   3147:  */
                   3148: void
                   3149: vm_object_collapse(
                   3150:        register vm_object_t    object)
                   3151: {
                   3152:        register vm_object_t    backing_object;
                   3153:        register vm_offset_t    backing_offset;
                   3154:        register vm_size_t      size;
                   3155:        register vm_offset_t    new_offset;
                   3156:        register vm_page_t      p;
                   3157: 
                   3158:        if (! vm_object_collapse_allowed && ! vm_object_bypass_allowed) {
                   3159:                return;
                   3160:        }
                   3161: 
                   3162:        XPR(XPR_VM_OBJECT, "vm_object_collapse, obj 0x%X\n", 
                   3163:                (integer_t)object, 0,0,0,0);
                   3164: 
                   3165:        while (TRUE) {
                   3166:                /*
                   3167:                 *      Verify that the conditions are right for either
                   3168:                 *      collapse or bypass:
                   3169:                 *
                   3170:                 *      The object exists and no pages in it are currently
                   3171:                 *      being paged out, and
                   3172:                 */
                   3173:                if (object == VM_OBJECT_NULL ||
                   3174:                    object->paging_in_progress != 0 ||
                   3175:                    object->absent_count != 0)
                   3176:                        return;
                   3177: 
                   3178:                /*
                   3179:                 *      There is a backing object, and
                   3180:                 */
                   3181:        
                   3182:                if ((backing_object = object->shadow) == VM_OBJECT_NULL)
                   3183:                        return;
                   3184:        
                   3185:                vm_object_lock(backing_object);
                   3186: 
                   3187:                /*
                   3188:                 *      ...
                   3189:                 *              The backing object is not read_only,
                   3190:                 *              and no pages in the backing object are
                   3191:                 *              currently being paged out.
                   3192:                 *              The backing object is internal.
                   3193:                 *
                   3194:                 */
                   3195:        
                   3196:                if (!backing_object->internal ||
                   3197:                    backing_object->paging_in_progress != 0) {
                   3198:                        vm_object_unlock(backing_object);
                   3199:                        return;
                   3200:                }
                   3201:        
                   3202:                /*
                   3203:                 *      The backing object can't be a copy-object:
                   3204:                 *      the shadow_offset for the copy-object must stay
                   3205:                 *      as 0.  Furthermore (for the 'we have all the
                   3206:                 *      pages' case), if we bypass backing_object and
                   3207:                 *      just shadow the next object in the chain, old
                   3208:                 *      pages from that object would then have to be copied
                   3209:                 *      BOTH into the (former) backing_object and into the
                   3210:                 *      parent object.
                   3211:                 */
                   3212:                if (backing_object->shadow != VM_OBJECT_NULL &&
                   3213:                    backing_object->shadow->copy != VM_OBJECT_NULL) {
                   3214:                        vm_object_unlock(backing_object);
                   3215:                        return;
                   3216:                }
                   3217: 
                   3218:                /*
                   3219:                 *      We can now try to either collapse the backing
                   3220:                 *      object (if the parent is the only reference to
                   3221:                 *      it) or (perhaps) remove the parent's reference
                   3222:                 *      to it.
                   3223:                 */
                   3224: 
                   3225:                /*
                   3226:                 *      If there is exactly one reference to the backing
                   3227:                 *      object, we may be able to collapse it into the parent.
                   3228:                 *
                   3229:                 *      XXXO (norma vm):
                   3230:                 *
                   3231:                 *      The backing object must not have a pager
                   3232:                 *      created for it, since collapsing an object
                   3233:                 *      into a backing_object dumps new pages into
                   3234:                 *      the backing_object that its pager doesn't
                   3235:                 *      know about, and we've already declared pages.
                   3236:                 *      This page dumping is deadly if other kernels
                   3237:                 *      are shadowing this object; this is the
                   3238:                 *      distributed equivalent of the ref_count == 1
                   3239:                 *      condition.
                   3240:                 *
                   3241:                 *      With some work, we could downgrade this
                   3242:                 *      restriction to the backing object must not
                   3243:                 *      be cachable, since when a temporary object
                   3244:                 *      is uncachable we are allowed to do anything
                   3245:                 *      to it. We would have to do something like
                   3246:                 *      call declare_pages again, and we would have
                   3247:                 *      to be prepared for the memory manager
                   3248:                 *      disabling temporary termination, which right
                   3249:                 *      now is a difficult race to deal with, since
                   3250:                 *      the memory manager currently assumes that
                   3251:                 *      termination is the only possible failure
                   3252:                 *      for disabling temporary termination.
                   3253:                 */
                   3254: 
                   3255:                if (backing_object->ref_count == 1 &&
                   3256:                    ! object->pager_created &&
                   3257:                    vm_object_collapse_allowed) {
                   3258: 
                   3259:                        XPR(XPR_VM_OBJECT, 
                   3260:                   "vm_object_collapse: %x to %x, pager %x, pager_request %x\n",
                   3261:                                (integer_t)backing_object, (integer_t)object,
                   3262:                                (integer_t)backing_object->pager, 
                   3263:                                (integer_t)backing_object->pager_request, 0);
                   3264: 
                   3265:                        /*
                   3266:                         *      We need the cache lock for collapsing,
                   3267:                         *      but we must not deadlock.
                   3268:                         */
                   3269:                        
                   3270:                        if (! vm_object_cache_lock_try()) {
                   3271:                                vm_object_unlock(backing_object);
                   3272:                                return;
                   3273:                        }
                   3274: 
                   3275:                        /*
                   3276:                         *      Collapse the object with its backing
                   3277:                         *      object, and try again with the object's
                   3278:                         *      new backing object.
                   3279:                         */
                   3280: 
                   3281:                        vm_object_do_collapse(object, backing_object);
                   3282:                        continue;
                   3283:                }
                   3284: 
                   3285: 
                   3286:                /*
                   3287:                 *      Collapsing the backing object was not possible
                   3288:                 *      or permitted, so let's try bypassing it.
                   3289:                 */
                   3290: 
                   3291:                if (! vm_object_bypass_allowed) {
                   3292:                        vm_object_unlock(backing_object);
                   3293:                        return;
                   3294:                }
                   3295: 
                   3296:                /*
                   3297:                 *      If the backing object has a pager but no pagemap,
                   3298:                 *      then we cannot bypass it, because we don't know
                   3299:                 *      what pages it has.
                   3300:                 */
                   3301:                if (backing_object->pager_created
                   3302: #if    MACH_PAGEMAP
                   3303:                    && (backing_object->existence_map == VM_EXTERNAL_NULL)
                   3304: #endif /* MACH_PAGEMAP */
                   3305:                    ) {
                   3306:                        vm_object_unlock(backing_object);
                   3307:                        return;
                   3308:                }
                   3309: 
                   3310:                backing_offset = object->shadow_offset;
                   3311:                size = object->size;
                   3312: 
                   3313:                /*
                   3314:                 *      If all of the pages in the backing object are
                   3315:                 *      shadowed by the parent object, the parent
                   3316:                 *      object no longer has to shadow the backing
                   3317:                 *      object; it can shadow the next one in the
                   3318:                 *      chain.
                   3319:                 *
                   3320:                 *      If the backing object has existence info,
                   3321:                 *      we must check examine its existence info
                   3322:                 *      as well.
                   3323:                 *
                   3324:                 *      XXX
                   3325:                 *      Should have a check for a 'small' number
                   3326:                 *      of pages here.
                   3327:                 */
                   3328: 
                   3329:                /*
                   3330:                 *      First, check pages resident in the backing object.
                   3331:                 */
                   3332: 
                   3333:                queue_iterate(&backing_object->memq, p, vm_page_t, listq) {
                   3334:                        
                   3335:                        /*
                   3336:                         *      If the parent has a page here, or if
                   3337:                         *      this page falls outside the parent,
                   3338:                         *      keep going.
                   3339:                         *
                   3340:                         *      Otherwise, the backing_object must be
                   3341:                         *      left in the chain.
                   3342:                         */
                   3343:                        
                   3344:                        new_offset = (p->offset - backing_offset);
                   3345:                        if (p->offset < backing_offset || new_offset >= size) {
                   3346: 
                   3347:                                /*
                   3348:                                 *      Page falls outside of parent.
                   3349:                                 *      Keep going.
                   3350:                                 */
                   3351: 
                   3352:                                continue;
                   3353:                        }
                   3354: 
                   3355:                        if ((vm_page_lookup(object, new_offset) == VM_PAGE_NULL)
                   3356: #if    MACH_PAGEMAP
                   3357:                            &&
                   3358:                            (vm_external_state_get(object->existence_map,
                   3359:                                        new_offset)
                   3360:                                        != VM_EXTERNAL_STATE_EXISTS)
                   3361: #endif /* MACH_PAGEMAP */
                   3362:                            ) {
                   3363: 
                   3364:                                /*
                   3365:                                 *      Page still needed.
                   3366:                                 *      Can't go any further.
                   3367:                                 */
                   3368: 
                   3369:                                vm_object_unlock(backing_object);
                   3370:                                return;
                   3371:                        }
                   3372:                }
                   3373: 
                   3374: #if    MACH_PAGEMAP
                   3375:                /*
                   3376:                 *      Next, if backing object has been paged out,
                   3377:                 *      we must check its existence info for pages
                   3378:                 *      that the parent doesn't have.
                   3379:                 */
                   3380: 
                   3381:                if (backing_object->pager_created) {
                   3382:                        assert(backing_object->existence_map
                   3383:                                        != VM_EXTERNAL_NULL);
                   3384:                        for (new_offset = 0; new_offset < object->size;
                   3385:                             new_offset += PAGE_SIZE) {
                   3386:                                vm_offset_t
                   3387:                                offset = new_offset + backing_offset;
                   3388: 
                   3389:                                /*
                   3390:                                 *      If this page doesn't exist in
                   3391:                                 *      the backing object's existence
                   3392:                                 *      info, then continue.
                   3393:                                 */
                   3394: 
                   3395:                                if (vm_external_state_get(
                   3396:                                        backing_object->existence_map,
                   3397:                                        offset) == VM_EXTERNAL_STATE_ABSENT) {
                   3398:                                        continue;
                   3399:                                }
                   3400: 
                   3401:                                /*
                   3402:                                 *      If this page is neither resident
                   3403:                                 *      in the parent nor paged out to
                   3404:                                 *      the parent's pager, then we cannot
                   3405:                                 *      bypass the backing object.
                   3406:                                 */
                   3407: 
                   3408:                                if ((vm_page_lookup(object, new_offset) ==
                   3409:                                     VM_PAGE_NULL) &&
                   3410:                                    ((object->existence_map == VM_EXTERNAL_NULL)
                   3411:                                        || (vm_external_state_get(
                   3412:                                        object->existence_map, new_offset)
                   3413:                                        == VM_EXTERNAL_STATE_ABSENT))) {
                   3414:                                        vm_object_unlock(backing_object);
                   3415:                                        return;
                   3416:                                }
                   3417:                        }
                   3418:                }
                   3419: #else  /* MACH_PAGEMAP */
                   3420:                assert(! backing_object->pager_created);
                   3421: #endif /* MACH_PAGEMAP */
                   3422: 
                   3423:                /*
                   3424:                 *      All interesting pages in the backing object
                   3425:                 *      already live in the parent or its pager.
                   3426:                 *      Thus we can bypass the backing object.
                   3427:                 */
                   3428: 
                   3429:                vm_object_do_bypass(object, backing_object);
                   3430: 
                   3431:                /*
                   3432:                 *      Try again with this object's new backing object.
                   3433:                 */
                   3434: 
                   3435:                continue;
                   3436:        }
                   3437: }
                   3438: 
                   3439: /*
                   3440:  *     Routine:        vm_object_page_remove: [internal]
                   3441:  *     Purpose:
                   3442:  *             Removes all physical pages in the specified
                   3443:  *             object range from the object's list of pages.
                   3444:  *
                   3445:  *     In/out conditions:
                   3446:  *             The object must be locked.
                   3447:  *             The object must not have paging_in_progress, usually
                   3448:  *             guaranteed by not having a pager.
                   3449:  */
                   3450: unsigned int vm_object_page_remove_lookup = 0;
                   3451: unsigned int vm_object_page_remove_iterate = 0;
                   3452: 
                   3453: void
                   3454: vm_object_page_remove(
                   3455:        register vm_object_t    object,
                   3456:        register vm_offset_t    start,
                   3457:        register vm_offset_t    end)
                   3458: {
                   3459:        register vm_page_t      p, next;
                   3460: 
                   3461:        /*
                   3462:         *      One and two page removals are most popular.
                   3463:         *      The factor of 16 here is somewhat arbitrary.
                   3464:         *      It balances vm_object_lookup vs iteration.
                   3465:         */
                   3466: 
                   3467:        if (atop(end - start) < (unsigned)object->resident_page_count/16) {
                   3468:                vm_object_page_remove_lookup++;
                   3469: 
                   3470:                for (; start < end; start += PAGE_SIZE) {
                   3471:                        p = vm_page_lookup(object, start);
                   3472:                        if (p != VM_PAGE_NULL) {
                   3473:                                assert(!p->cleaning && !p->pageout);
                   3474:                                if (!p->fictitious)
                   3475:                                        pmap_page_protect(p->phys_addr,
                   3476:                                                          VM_PROT_NONE);
                   3477:                                VM_PAGE_FREE(p);
                   3478:                        }
                   3479:                }
                   3480:        } else {
                   3481:                vm_object_page_remove_iterate++;
                   3482: 
                   3483:                p = (vm_page_t) queue_first(&object->memq);
                   3484:                while (!queue_end(&object->memq, (queue_entry_t) p)) {
                   3485:                        next = (vm_page_t) queue_next(&p->listq);
                   3486:                        if ((start <= p->offset) && (p->offset < end)) {
                   3487:                                assert(!p->cleaning && !p->pageout);
                   3488:                                if (!p->fictitious)
                   3489:                                    pmap_page_protect(p->phys_addr,
                   3490:                                                      VM_PROT_NONE);
                   3491:                                VM_PAGE_FREE(p);
                   3492:                        }
                   3493:                        p = next;
                   3494:                }
                   3495:        }
                   3496: }
                   3497: 
                   3498: /*
                   3499:  *     Routine:        vm_object_coalesce
                   3500:  *     Function:       Coalesces two objects backing up adjoining
                   3501:  *                     regions of memory into a single object.
                   3502:  *
                   3503:  *     returns TRUE if objects were combined.
                   3504:  *
                   3505:  *     NOTE:   Only works at the moment if the second object is NULL -
                   3506:  *             if it's not, which object do we lock first?
                   3507:  *
                   3508:  *     Parameters:
                   3509:  *             prev_object     First object to coalesce
                   3510:  *             prev_offset     Offset into prev_object
                   3511:  *             next_object     Second object into coalesce
                   3512:  *             next_offset     Offset into next_object
                   3513:  *
                   3514:  *             prev_size       Size of reference to prev_object
                   3515:  *             next_size       Size of reference to next_object
                   3516:  *
                   3517:  *     Conditions:
                   3518:  *     The object(s) must *not* be locked. The map must be locked
                   3519:  *     to preserve the reference to the object(s).
                   3520:  */
                   3521: int vm_object_coalesce_count = 0;
                   3522: 
                   3523: boolean_t
                   3524: vm_object_coalesce(
                   3525:        register vm_object_t    prev_object,
                   3526:        vm_object_t             next_object,
                   3527:        vm_offset_t             prev_offset,
                   3528:        vm_offset_t             next_offset,
                   3529:        vm_size_t               prev_size,
                   3530:        vm_size_t               next_size)
                   3531: {
                   3532:        vm_size_t       newsize;
                   3533: 
                   3534: #ifdef lint
                   3535:        next_offset++;
                   3536: #endif /* lint */
                   3537: 
                   3538:        if (next_object != VM_OBJECT_NULL) {
                   3539:                return(FALSE);
                   3540:        }
                   3541: 
                   3542:        if (prev_object == VM_OBJECT_NULL) {
                   3543:                return(TRUE);
                   3544:        }
                   3545: 
                   3546:        XPR(XPR_VM_OBJECT,
                   3547:        "vm_object_coalesce: 0x%X prev_off 0x%X prev_size 0x%X next_size 0x%X\n",
                   3548:                (integer_t)prev_object, prev_offset, prev_size, next_size, 0);
                   3549: 
                   3550:        vm_object_lock(prev_object);
                   3551: 
                   3552:        /*
                   3553:         *      Try to collapse the object first
                   3554:         */
                   3555:        vm_object_collapse(prev_object);
                   3556: 
                   3557:        /*
                   3558:         *      Can't coalesce if pages not mapped to
                   3559:         *      prev_entry may be in use any way:
                   3560:         *      . more than one reference
                   3561:         *      . paged out
                   3562:         *      . shadows another object
                   3563:         *      . has a copy elsewhere
                   3564:         *      . paging references (pages might be in page-list)
                   3565:         */
                   3566: 
                   3567:        if ((prev_object->ref_count > 1) ||
                   3568:            prev_object->pager_created ||
                   3569:            (prev_object->shadow != VM_OBJECT_NULL) ||
                   3570:            (prev_object->copy != VM_OBJECT_NULL) ||
                   3571:            (prev_object->true_share != FALSE) ||
                   3572:            (prev_object->paging_in_progress != 0)) {
                   3573:                vm_object_unlock(prev_object);
                   3574:                return(FALSE);
                   3575:        }
                   3576: 
                   3577:        vm_object_coalesce_count++;
                   3578: 
                   3579:        /*
                   3580:         *      Remove any pages that may still be in the object from
                   3581:         *      a previous deallocation.
                   3582:         */
                   3583:        vm_object_page_remove(prev_object,
                   3584:                prev_offset + prev_size,
                   3585:                prev_offset + prev_size + next_size);
                   3586: 
                   3587:        /*
                   3588:         *      Extend the object if necessary.
                   3589:         */
                   3590:        newsize = prev_offset + prev_size + next_size;
                   3591:        if (newsize > prev_object->size) {
                   3592: #if    MACH_PAGEMAP
                   3593:                /*
                   3594:                 *      We cannot extend an object that has existence info,
                   3595:                 *      since the existence info might then fail to cover
                   3596:                 *      the entire object.
                   3597:                 *
                   3598:                 *      This assertion must be true because the object
                   3599:                 *      has no pager, and we only create existence info
                   3600:                 *      for objects with pagers.
                   3601:                 */
                   3602:                assert(prev_object->existence_map == VM_EXTERNAL_NULL);
                   3603: #endif /* MACH_PAGEMAP */
                   3604:                prev_object->size = newsize;
                   3605:        }
                   3606: 
                   3607:        vm_object_unlock(prev_object);
                   3608:        return(TRUE);
                   3609: }
                   3610: 
                   3611: /*
                   3612:  *     Attach a set of physical pages to an object, so that they can
                   3613:  *     be mapped by mapping the object.  Typically used to map IO memory.
                   3614:  *
                   3615:  *     The mapping function and its private data are used to obtain the
                   3616:  *     physical addresses for each page to be mapped.
                   3617:  */
                   3618: void
                   3619: vm_object_page_map(
                   3620:        vm_object_t     object,
                   3621:        vm_offset_t     offset,
                   3622:        vm_size_t       size,
                   3623:        vm_offset_t     (*map_fn)(void *map_fn_data, vm_offset_t offset),
                   3624:        void            *map_fn_data)   /* private to map_fn */
                   3625: {
                   3626:        int     num_pages;
                   3627:        int     i;
                   3628:        vm_page_t       m;
                   3629:        vm_page_t       old_page;
                   3630:        vm_offset_t     addr;
                   3631: 
                   3632:        num_pages = atop(size);
                   3633: 
                   3634:        for (i = 0; i < num_pages; i++, offset += PAGE_SIZE) {
                   3635: 
                   3636:            addr = (*map_fn)(map_fn_data, offset);
                   3637: 
                   3638:            while ((m = vm_page_grab_fictitious()) == VM_PAGE_NULL)
                   3639:                vm_page_more_fictitious();
                   3640: 
                   3641:            vm_object_lock(object);
                   3642:            if ((old_page = vm_page_lookup(object, offset))
                   3643:                        != VM_PAGE_NULL)
                   3644:            {
                   3645:                vm_page_lock_queues();
                   3646:                vm_page_free(old_page);
                   3647:                vm_page_unlock_queues();
                   3648:            }
                   3649: 
                   3650:            vm_page_init(m, addr);
                   3651:            m->private = TRUE;          /* don`t free page */
                   3652:            m->wire_count = 1;
                   3653:            vm_page_insert(m, object, offset);
                   3654: 
                   3655:            PAGE_WAKEUP_DONE(m);
                   3656:            vm_object_unlock(object);
                   3657:        }
                   3658: }
                   3659: 
                   3660: #include <mach_kdb.h>
                   3661: 
                   3662: #if    MACH_KDB
                   3663: #include <ddb/db_output.h>
                   3664: #include <vm/vm_print.h>
                   3665: 
                   3666: #define printf kdbprintf
                   3667: 
                   3668: extern boolean_t       vm_object_cached(
                   3669:                                vm_object_t object);
                   3670: 
                   3671: extern void            print_bitstring(
                   3672:                                char byte);
                   3673: 
                   3674: boolean_t      vm_object_print_pages = FALSE;
                   3675: 
                   3676: void
                   3677: print_bitstring(
                   3678:        char byte)
                   3679: {
                   3680:        printf("%c%c%c%c%c%c%c%c",
                   3681:               ((byte & (1 << 0)) ? '1' : '0'),
                   3682:               ((byte & (1 << 1)) ? '1' : '0'),
                   3683:               ((byte & (1 << 2)) ? '1' : '0'),
                   3684:               ((byte & (1 << 3)) ? '1' : '0'),
                   3685:               ((byte & (1 << 4)) ? '1' : '0'),
                   3686:               ((byte & (1 << 5)) ? '1' : '0'),
                   3687:               ((byte & (1 << 6)) ? '1' : '0'),
                   3688:               ((byte & (1 << 7)) ? '1' : '0'));
                   3689: }
                   3690: 
                   3691: boolean_t
                   3692: vm_object_cached(
                   3693:        register vm_object_t object)
                   3694: {
                   3695:        register vm_object_t o;
                   3696: 
                   3697:        queue_iterate(&vm_object_cached_list, o, vm_object_t, cached_list) {
                   3698:                if (object == o) {
                   3699:                        return TRUE;
                   3700:                }
                   3701:        }
                   3702:        return FALSE;
                   3703: }
                   3704: 
                   3705: #if    MACH_PAGEMAP
                   3706: /*
                   3707:  *     vm_external_print:      [ debug ]
                   3708:  */
                   3709: void
                   3710: vm_external_print(
                   3711:        vm_external_map_t map,
                   3712:        vm_size_t       size)
                   3713: {
                   3714:        if (map == VM_EXTERNAL_NULL) {
                   3715:                printf("0  ");
                   3716:        } else {
                   3717:                vm_size_t existence_size = stob(size);
                   3718:                printf("{ size=%d, map=[", existence_size);
                   3719:                if (existence_size > 0) {
                   3720:                        print_bitstring(map[0]);
                   3721:                }
                   3722:                if (existence_size > 1) {
                   3723:                        print_bitstring(map[1]);
                   3724:                }
                   3725:                if (existence_size > 2) {
                   3726:                        printf("...");
                   3727:                        print_bitstring(map[existence_size-1]);
                   3728:                }
                   3729:                printf("] }\n");
                   3730:        }
                   3731:        return;
                   3732: }
                   3733: #endif /* MACH_PAGEMAP */
                   3734: 
                   3735: int
                   3736: vm_follow_object(
                   3737:        vm_object_t object)
                   3738: {
                   3739:        extern db_indent;
                   3740: 
                   3741:        int count = 1;
                   3742: 
                   3743:        if (object == VM_OBJECT_NULL)
                   3744:                return 0;
                   3745: 
                   3746:        iprintf("object 0x%x", object);
                   3747:        printf(", shadow=0x%x", object->shadow);
                   3748:        printf(", copy=0x%x", object->copy);
                   3749:        printf(", pager=0x%x", object->pager);
                   3750:        printf(", ref=%d\n", object->ref_count);
                   3751: 
                   3752:        db_indent += 2;
                   3753:        if (object->shadow)
                   3754:            count += vm_follow_object(object->shadow);
                   3755: 
                   3756:        db_indent -= 2;
                   3757:        return count;
                   3758: }
                   3759: 
                   3760: /*
                   3761:  *     vm_object_print:        [ debug ]
                   3762:  */
                   3763: void
                   3764: vm_object_print(
                   3765:        vm_object_t     object,
                   3766:        boolean_t       have_addr,
                   3767:        int             arg_count,
                   3768:        char            *modif)
                   3769: {
                   3770:        register vm_page_t p;
                   3771:        extern db_indent;
                   3772:        char *s;
                   3773: 
                   3774:        register int count;
                   3775: 
                   3776:        if (object == VM_OBJECT_NULL)
                   3777:                return;
                   3778: 
                   3779:        iprintf("object 0x%x\n", object);
                   3780: 
                   3781:        db_indent += 2;
                   3782: 
                   3783:        iprintf("size=0x%x", object->size);
                   3784:        printf(", cluster=0x%x", object->cluster_size);
                   3785:        printf(", frozen=0x%x", object->frozen_size);
                   3786:        printf(", ref_count=%d\n", object->ref_count);
                   3787:        iprintf("");
                   3788: #if    TASK_SWAPPER
                   3789:        printf("res_count=%d, ", object->res_count);
                   3790: #endif /* TASK_SWAPPER */
                   3791:        printf("resident_page_count=%d\n", object->resident_page_count);
                   3792: 
                   3793:        iprintf("shadow=0x%x", object->shadow);
                   3794:        if (object->shadow) {
                   3795:                register int i = 0;
                   3796:                vm_object_t shadow = object;
                   3797:                while(shadow = shadow->shadow)
                   3798:                        i++;
                   3799:                printf(" (depth %d)", i);
                   3800:        }
                   3801:        printf(", copy=0x%x", object->copy);
                   3802:        printf(", shadow_offset=0x%x", object->shadow_offset);
                   3803:        printf(", last_alloc=0x%x\n", object->last_alloc);
                   3804: 
                   3805:        iprintf("pager=0x%x", object->pager);
                   3806:        printf(", paging_offset=0x%x", object->paging_offset);
                   3807:        printf(", pager_request=0x%x\n", object->pager_request);
                   3808: 
                   3809:        iprintf("copy_strategy=%d[", object->copy_strategy);
                   3810:        switch (object->copy_strategy) {
                   3811:                case MEMORY_OBJECT_COPY_NONE:
                   3812:                printf("copy_none");
                   3813:                break;
                   3814: 
                   3815:                case MEMORY_OBJECT_COPY_CALL:
                   3816:                printf("copy_call");
                   3817:                break;
                   3818: 
                   3819:                case MEMORY_OBJECT_COPY_DELAY:
                   3820:                printf("copy_delay");
                   3821:                break;
                   3822: 
                   3823:                case MEMORY_OBJECT_COPY_SYMMETRIC:
                   3824:                printf("copy_symmetric");
                   3825:                break;
                   3826: 
                   3827:                case MEMORY_OBJECT_COPY_INVALID:
                   3828:                printf("copy_invalid");
                   3829:                break;
                   3830: 
                   3831:                default:
                   3832:                printf("?");
                   3833:        }
                   3834:        printf("]");
                   3835:        printf(", absent_count=%d\n", object->absent_count);
                   3836: 
                   3837:        iprintf("all_wanted=0x%x<", object->all_wanted);
                   3838:        s = "";
                   3839:        if (vm_object_wanted(object, VM_OBJECT_EVENT_INITIALIZED)) {
                   3840:                printf("%sinit", s);
                   3841:                s = ",";
                   3842:        }
                   3843:        if (vm_object_wanted(object, VM_OBJECT_EVENT_PAGER_READY)) {
                   3844:                printf("%sready", s);
                   3845:                s = ",";
                   3846:        }
                   3847:        if (vm_object_wanted(object, VM_OBJECT_EVENT_PAGING_IN_PROGRESS)) {
                   3848:                printf("%spaging", s);
                   3849:                s = ",";
                   3850:        }
                   3851:        if (vm_object_wanted(object, VM_OBJECT_EVENT_ABSENT_COUNT)) {
                   3852:                printf("%sabsent", s);
                   3853:                s = ",";
                   3854:        }
                   3855:        if (vm_object_wanted(object, VM_OBJECT_EVENT_LOCK_IN_PROGRESS)) {
                   3856:                printf("%slock", s);
                   3857:                s = ",";
                   3858:        }
                   3859:        if (vm_object_wanted(object, VM_OBJECT_EVENT_UNCACHING)) {
                   3860:                printf("%suncaching", s);
                   3861:                s = ",";
                   3862:        }
                   3863:        if (vm_object_wanted(object, VM_OBJECT_EVENT_COPY_CALL)) {
                   3864:                printf("%scopy_call", s);
                   3865:                s = ",";
                   3866:        }
                   3867:        if (vm_object_wanted(object, VM_OBJECT_EVENT_CACHING)) {
                   3868:                printf("%scaching", s);
                   3869:                s = ",";
                   3870:        }
                   3871:        printf(">");
                   3872:        printf(", paging_in_progress=%d\n", object->paging_in_progress);
                   3873: 
                   3874:        iprintf("%screated, %sinit, %sready, %spersist, %strusted, %spageout, %s, %s\n",
                   3875:                (object->pager_created ? "" : "!"),
                   3876:                (object->pager_initialized ? "" : "!"),
                   3877:                (object->pager_ready ? "" : "!"),
                   3878:                (object->can_persist ? "" : "!"),
                   3879:                (object->pager_trusted ? "" : "!"),
                   3880:                (object->pageout ? "" : "!"),
                   3881:                (object->internal ? "internal" : "external"),
                   3882:                (object->temporary ? "temporary" : "permanent"));
                   3883:        iprintf("%salive, %slock_in_progress, %slock_restart, %sshadowed, %scached, %sprivate\n",
                   3884:                (object->alive ? "" : "!"),
                   3885:                (object->lock_in_progress ? "" : "!"),
                   3886:                (object->lock_restart ? "" : "!"),
                   3887:                (object->shadowed ? "" : "!"),
                   3888:                (vm_object_cached(object) ? "" : "!"),
                   3889:                (object->private ? "" : "!"));
                   3890:        iprintf("%sadvisory_pageout, %ssilent_overwrite\n",
                   3891:                (object->advisory_pageout ? "" : "!"),
                   3892:                (object->silent_overwrite ? "" : "!"));
                   3893: 
                   3894: #if    MACH_PAGEMAP
                   3895:        iprintf("existence_map=");
                   3896:        vm_external_print(object->existence_map, object->size);
                   3897: #endif /* MACH_PAGEMAP */
                   3898: #if    MACH_ASSERT
                   3899:        iprintf("paging_object=0x%x\n", object->paging_object);
                   3900: #endif /* MACH_ASSERT */
                   3901: 
                   3902:        if (vm_object_print_pages) {
                   3903:                count = 0;
                   3904:                p = (vm_page_t) queue_first(&object->memq);
                   3905:                while (!queue_end(&object->memq, (queue_entry_t) p)) {
                   3906:                        if (count == 0) {
                   3907:                                iprintf("memory:=");
                   3908:                        } else if (count == 2) {
                   3909:                                printf("\n");
                   3910:                                iprintf(" ...");
                   3911:                                count = 0;
                   3912:                        } else {
                   3913:                                printf(",");
                   3914:                        }
                   3915:                        count++;
                   3916: 
                   3917:                        printf("(off=0x%X,page=0x%X)", p->offset, (integer_t) p);
                   3918:                        p = (vm_page_t) queue_next(&p->listq);
                   3919:                }
                   3920:                if (count != 0) {
                   3921:                        printf("\n");
                   3922:                }
                   3923:        }
                   3924:        db_indent -= 2;
                   3925: }
                   3926: 
                   3927: 
                   3928: /*
                   3929:  *     vm_object_find          [ debug ]
                   3930:  *
                   3931:  *     Find all tasks which reference the given vm_object.
                   3932:  */
                   3933: 
                   3934: boolean_t vm_object_find(vm_object_t object);
                   3935: boolean_t vm_object_print_verbose = FALSE;
                   3936: 
                   3937: boolean_t
                   3938: vm_object_find(
                   3939:        vm_object_t     object)
                   3940: {
                   3941:         task_t task;
                   3942:        vm_map_t map;
                   3943:        vm_map_entry_t entry;
                   3944:         processor_set_t pset;
                   3945:        boolean_t found = FALSE;
                   3946: 
                   3947:         queue_iterate(&all_psets, pset, processor_set_t, all_psets) {
                   3948:             queue_iterate(&pset->tasks, task, task_t, pset_tasks) {
                   3949:                map = task->map;
                   3950:                for (entry = vm_map_first_entry(map);
                   3951:                      entry && entry != vm_map_to_entry(map);
                   3952:                      entry = entry->vme_next) {
                   3953: 
                   3954:                        vm_object_t obj;
                   3955: 
                   3956:                        /* 
                   3957:                         * For the time being skip submaps,
                   3958:                         * only the kernel can have submaps,
                   3959:                         * and unless we are interested in 
                   3960:                         * kernel objects, we can simply skip 
                   3961:                         * submaps. See sb/dejan/nmk18b7/src/mach_kernel/vm
                   3962:                         * for a full solution.
                   3963:                         */
                   3964:                        if (entry->is_sub_map)
                   3965:                                continue;
                   3966:                        if (entry) 
                   3967:                                obj = entry->object.vm_object;
                   3968:                        else 
                   3969:                                continue;
                   3970: 
                   3971:                        while (obj != VM_OBJECT_NULL) {
                   3972:                                if (obj == object) {
                   3973:                                        if (!found) {
                   3974:                                                printf("TASK\t\tMAP\t\tENTRY\n");
                   3975:                                                found = TRUE;
                   3976:                                        }
                   3977:                                        printf("0x%x\t0x%x\t0x%x\n", 
                   3978:                                                        task, map, entry);
                   3979:                                }
                   3980:                                obj = obj->shadow;
                   3981:                        }
                   3982:                }
                   3983:             }
                   3984:         }
                   3985: 
                   3986:        return(found);
                   3987: }
                   3988: 
                   3989: #endif /* MACH_KDB */
                   3990: 
                   3991: /*
                   3992:  *     memory_object_free_from_cache:
                   3993:  *
                   3994:  *     Walk the vm_object cache list, removing and freeing vm_objects 
                   3995:  *     which are backed by the pager identified by the caller, (pager_id).  
                   3996:  *     Remove up to "count" objects, if there are that may available
                   3997:  *     in the cache.
                   3998:  *     Walk the list at most once, return the number of vm_objects
                   3999:  *     actually freed.
                   4000:  *
                   4001:  */
                   4002: 
                   4003: kern_return_t
                   4004: memory_object_free_from_cache(
                   4005:        host_t          host,
                   4006:        int             pager_id,
                   4007:        int             *count)
                   4008: {
                   4009: 
                   4010:        int     object_released = 0;
                   4011:        int     i;
                   4012: 
                   4013:        register vm_object_t object = VM_OBJECT_NULL;
                   4014:        vm_object_t shadow;
                   4015: 
                   4016:        if(host == HOST_NULL)
                   4017:                return(KERN_INVALID_ARGUMENT);
                   4018: 
                   4019:  try_again:
                   4020:        vm_object_cache_lock();
                   4021: 
                   4022:        queue_iterate(&vm_object_cached_list, object, 
                   4023:                                        vm_object_t, cached_list) {
                   4024:                if (pager_id == (int) pager_mux_hash_lookup(
                   4025:                                        (ipc_port_t)object->pager)) {
                   4026:                        vm_object_lock(object);
                   4027:                        queue_remove(&vm_object_cached_list, object, 
                   4028:                                        vm_object_t, cached_list);
                   4029:                        vm_object_cached_count--;
                   4030: 
                   4031:                        /*
                   4032:                        *       Since this object is in the cache, we know
                   4033:                        *       that it is initialized and has no references.
                   4034:                        *       Take a reference to avoid recursive 
                   4035:                        *       deallocations.
                   4036:                        */
                   4037: 
                   4038:                        assert(object->pager_initialized);
                   4039:                        assert(object->ref_count == 0);
                   4040:                        object->ref_count++;
                   4041: 
                   4042:                        /*
                   4043:                        *       Terminate the object.
                   4044:                        *       If the object had a shadow, we let 
                   4045:                        *       vm_object_deallocate deallocate it. 
                   4046:                        *       "pageout" objects have a shadow, but
                   4047:                        *       maintain a "paging reference" rather 
                   4048:                        *       than a normal reference.
                   4049:                        *       (We are careful here to limit recursion.)
                   4050:                        */
                   4051:                        shadow = object->pageout?VM_OBJECT_NULL:object->shadow;
                   4052:                        vm_object_terminate(object);
                   4053:                        if (shadow != VM_OBJECT_NULL) {
                   4054:                                vm_object_deallocate(shadow);
                   4055:                        }
                   4056:                
                   4057:                        if(object_released++ == *count)
                   4058:                                return KERN_SUCCESS;
                   4059:                        goto try_again;
                   4060:                }
                   4061:        }
                   4062:        vm_object_cache_unlock();
                   4063:        *count  = object_released;
                   4064:        return KERN_SUCCESS;
                   4065: }
                   4066: 
                   4067: /*
                   4068:  *     memory_object_remove_cached_object:
                   4069:  *
                   4070:  *     Check for the existance of a memory object represented by the
                   4071:  *     supplied port.  If one exists and it is not in use, remove the 
                   4072:  *     memory object from the vm_object cache.
                   4073:  *     If the memory object is in use, turn off the the "can_persist"
                   4074:  *     property so that it will not go in the cache when the last user 
                   4075:  *     gives it up.
                   4076:  *
                   4077:  */
                   4078: 
                   4079: kern_return_t
                   4080: memory_object_remove_cached_object(
                   4081:        ipc_port_t      port)
                   4082: {
                   4083:        vm_object_t     object;
                   4084:        vm_object_t     shadow;
                   4085: 
                   4086: repeat_lock_acquire:
                   4087:        object = VM_OBJECT_NULL;
                   4088: 
                   4089:        if (IP_VALID(port)) {
                   4090:                vm_object_cache_lock();
                   4091:                ip_lock(port);
                   4092:                if (ip_active(port) &&
                   4093:                    (ip_kotype(port) == IKOT_PAGER_LOOKUP_TYPE)) {
                   4094:                        object = (vm_object_t) port->ip_kobject;
                   4095:                        if (!vm_object_lock_try(object)) {
                   4096:                                /*
                   4097:                                 * failed to acquire object lock.  Drop the
                   4098:                                 * other two locks and wait for it, then go
                   4099:                                 * back and start over in case the port
                   4100:                                 * associations changed in the interim.
                   4101:                                 */
                   4102:                                ip_unlock(port);
                   4103:                                vm_object_cache_unlock();
                   4104:                                vm_object_lock(object);
                   4105:                                vm_object_unlock(object);
                   4106:                                goto repeat_lock_acquire;
                   4107:                        }
                   4108: 
                   4109:                        assert(object->alive);
                   4110:                        ip_unlock(port);
                   4111: 
                   4112:                        if (object->ref_count == 0) {
                   4113:                                queue_remove(&vm_object_cached_list, object,
                   4114:                                             vm_object_t, cached_list);
                   4115:                                vm_object_cached_count--;
                   4116:                                object->ref_count++;
                   4117:                                /*
                   4118:                                *       Terminate the object.
                   4119:                                *       If the object had a shadow, we let
                   4120:                                *       vm_object_deallocate deallocate it.
                   4121:                                *       "pageout" objects have a shadow, but
                   4122:                                *       maintain a "paging reference" rather
                   4123:                                *       than a normal reference.
                   4124:                                *       (We are careful here to limit 
                   4125:                                *       recursion.)
                   4126:                                */
                   4127:                                shadow = object->pageout?
                   4128:                                        VM_OBJECT_NULL:object->shadow;
                   4129:                                /* will do the vm_object_cache_unlock */
                   4130:                                vm_object_terminate(object);
                   4131:                                if (shadow != VM_OBJECT_NULL) {
                   4132:                                        /* will lock and unlock cache_lock */
                   4133:                                        vm_object_deallocate(shadow);
                   4134:                                }
                   4135:                        }
                   4136:                        else {
                   4137:                                /* 
                   4138:                                *       We cannot free object but we can
                   4139:                                *       make sure it doesn't go into the 
                   4140:                                *       cache when it is no longer in
                   4141:                                *       use.
                   4142:                                */ 
                   4143:                                object->can_persist = FALSE;
                   4144: 
                   4145:                                vm_object_unlock(object);
                   4146:                                vm_object_cache_unlock();
                   4147:                                return KERN_RIGHT_EXISTS;
                   4148:                        }
                   4149: 
                   4150: 
                   4151:                }
                   4152:                else {
                   4153:                        ip_unlock(port);
                   4154:                        vm_object_cache_unlock();
                   4155:                }
                   4156:        } else {
                   4157:                return KERN_INVALID_ARGUMENT;
                   4158:        }
                   4159: 
                   4160: 
                   4161:        return KERN_SUCCESS;
                   4162: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.