Annotation of Net2/vm/vm_object.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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