Annotation of Net2/vm/vm_pager.c, revision 1.1.1.2

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_pager.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.
1.1.1.2 ! root       63:  *
        !            64:  * PATCHES MAGIC                LEVEL   PATCH THAT GOT US HERE
        !            65:  * --------------------         -----   ----------------------
        !            66:  * CURRENT PATCH LEVEL:         1       00063
        !            67:  * --------------------         -----   ----------------------
        !            68:  *
        !            69:  * 28 Nov 1991 Poul-Henning Kamp       Speedup processing
1.1       root       70:  */
                     71: 
                     72: /*
                     73:  *     Paging space routine stubs.  Emulates a matchmaker-like interface
                     74:  *     for builtin pagers.
                     75:  */
                     76: 
                     77: #include "param.h"
                     78: #include "malloc.h"
                     79: 
                     80: #include "vm.h"
                     81: #include "vm_page.h"
                     82: #include "vm_kern.h"
                     83: 
                     84: #include "swappager.h"
                     85: 
                     86: #if NSWAPPAGER > 0
                     87: extern struct pagerops swappagerops;
                     88: #else
                     89: #define        swappagerops    NULL
                     90: #endif
                     91: #include "vnodepager.h"
                     92: #if NVNODEPAGER > 0
                     93: extern struct pagerops vnodepagerops;
                     94: #else
                     95: #define        vnodepagerops   NULL
                     96: #endif
                     97: #include "devpager.h"
                     98: #if NDEVPAGER > 0
                     99: extern struct pagerops devicepagerops;
                    100: #else
                    101: #define        devicepagerops  NULL
                    102: #endif
                    103: 
                    104: struct pagerops *pagertab[] = {
                    105:        &swappagerops,          /* PG_SWAP */
                    106:        &vnodepagerops,         /* PG_VNODE */
                    107:        &devicepagerops,        /* PG_DEV */
                    108: };
                    109: int npagers = sizeof (pagertab) / sizeof (pagertab[0]);
                    110: 
                    111: struct pagerops *dfltpagerops = NULL;  /* default pager */
                    112: 
                    113: /*
                    114:  * Kernel address space for mapping pages.
                    115:  * Used by pagers where KVAs are needed for IO.
                    116:  */
                    117: #define PAGER_MAP_SIZE (256 * PAGE_SIZE)
                    118: vm_map_t pager_map;
                    119: vm_offset_t pager_sva, pager_eva;
                    120: 
                    121: void
                    122: vm_pager_init()
                    123: {
                    124:        struct pagerops **pgops;
                    125: 
                    126:        /*
                    127:         * Allocate a kernel submap for tracking get/put page mappings
                    128:         */
                    129:        pager_map = kmem_suballoc(kernel_map, &pager_sva, &pager_eva,
                    130:                                  PAGER_MAP_SIZE, FALSE);
                    131:        /*
                    132:         * Initialize known pagers
                    133:         */
                    134:        for (pgops = pagertab; pgops < &pagertab[npagers]; pgops++)
                    135:                (*(*pgops)->pgo_init)();
                    136:        if (dfltpagerops == NULL)
                    137:                panic("no default pager");
                    138: }
                    139: 
                    140: /*
                    141:  * Allocate an instance of a pager of the given type.
                    142:  */
                    143: vm_pager_t
                    144: vm_pager_allocate(type, handle, size, prot)
                    145:        int type;
                    146:        caddr_t handle;
                    147:        vm_size_t size;
                    148:        vm_prot_t prot;
                    149: {
                    150:        vm_pager_t pager;
                    151:        struct pagerops *ops;
                    152: 
                    153:        ops = (type == PG_DFLT) ? dfltpagerops : pagertab[type];
                    154:        return((*ops->pgo_alloc)(handle, size, prot));
                    155: }
                    156: 
                    157: void
                    158: vm_pager_deallocate(pager)
                    159:        vm_pager_t      pager;
                    160: {
                    161:        if (pager == NULL)
                    162:                panic("vm_pager_deallocate: null pager");
                    163: 
                    164:        VM_PAGER_DEALLOC(pager);
                    165: }
                    166: 
                    167: vm_pager_get(pager, m, sync)
                    168:        vm_pager_t      pager;
                    169:        vm_page_t       m;
                    170:        boolean_t       sync;
                    171: {
                    172:        extern boolean_t vm_page_zero_fill();
                    173: 
                    174:        if (pager == NULL)
                    175:                return(vm_page_zero_fill(m) ? VM_PAGER_OK : VM_PAGER_FAIL);
                    176:        return(VM_PAGER_GET(pager, m, sync));
                    177: }
                    178: 
                    179: vm_pager_put(pager, m, sync)
                    180:        vm_pager_t      pager;
                    181:        vm_page_t       m;
                    182:        boolean_t       sync;
                    183: {
                    184:        if (pager == NULL)
                    185:                panic("vm_pager_put: null pager");
                    186:        return(VM_PAGER_PUT(pager, m, sync));
                    187: }
                    188: 
                    189: boolean_t
                    190: vm_pager_has_page(pager, offset)
                    191:        vm_pager_t      pager;
                    192:        vm_offset_t     offset;
                    193: {
                    194:        if (pager == NULL)
                    195:                panic("vm_pager_has_page");
                    196:        return(VM_PAGER_HASPAGE(pager, offset));
                    197: }
                    198: 
                    199: /*
                    200:  * Called by pageout daemon before going back to sleep.
                    201:  * Gives pagers a chance to clean up any completed async pageing operations.
                    202:  */
                    203: void
                    204: vm_pager_sync()
                    205: {
                    206:        struct pagerops **pgops;
                    207: 
                    208:        for (pgops = pagertab; pgops < &pagertab[npagers]; pgops++)
                    209:                (*(*pgops)->pgo_putpage)(NULL, NULL, FALSE);
                    210: }
                    211: 
                    212: vm_offset_t
                    213: vm_pager_map_page(m)
                    214:        vm_page_t       m;
                    215: {
                    216:        vm_offset_t kva;
                    217: 
                    218: #ifdef DEBUG
                    219:        if (!m->busy || m->active)
                    220:                panic("vm_pager_map_page: page active or not busy");
                    221:        if (m->pagerowned)
                    222:                printf("vm_pager_map_page: page %x already in pager\n", m);
                    223: #endif
                    224:        kva = kmem_alloc_wait(pager_map, PAGE_SIZE);
                    225: #ifdef DEBUG
                    226:        m->pagerowned = 1;
                    227: #endif
                    228:        pmap_enter(vm_map_pmap(pager_map), kva, VM_PAGE_TO_PHYS(m),
                    229:                   VM_PROT_DEFAULT, TRUE);
                    230:        return(kva);
                    231: }
                    232: 
                    233: void
                    234: vm_pager_unmap_page(kva)
                    235:        vm_offset_t     kva;
                    236: {
                    237: #ifdef DEBUG
                    238:        vm_page_t m;
                    239: 
                    240:        m = PHYS_TO_VM_PAGE(pmap_extract(vm_map_pmap(pager_map), kva));
                    241: #endif
                    242:        kmem_free_wakeup(pager_map, kva, PAGE_SIZE);
                    243: #ifdef DEBUG
                    244:        if (m->pagerowned)
                    245:                m->pagerowned = 0;
                    246:        else
                    247:                printf("vm_pager_unmap_page: page %x(%x/%x) not owned\n",
                    248:                       m, kva, VM_PAGE_TO_PHYS(m));
                    249: #endif
                    250: }
                    251: 
                    252: vm_pager_t
                    253: vm_pager_lookup(list, handle)
                    254:        register queue_head_t *list;
                    255:        caddr_t handle;
                    256: {
                    257:        register vm_pager_t pager;
                    258: 
                    259:        pager = (vm_pager_t) queue_first(list);
                    260:        while (!queue_end(list, (queue_entry_t)pager)) {
                    261:                if (pager->pg_handle == handle)
                    262:                        return(pager);
                    263:                pager = (vm_pager_t) queue_next(&pager->pg_list);
                    264:        }
                    265:        return(NULL);
                    266: }
                    267: 
                    268: /*
                    269:  * This routine gains a reference to the object.
                    270:  * Explicit deallocation is necessary.
                    271:  */
                    272: pager_cache(object, should_cache)
                    273:        vm_object_t     object;
                    274:        boolean_t       should_cache;
                    275: {
                    276:        if (object == NULL)
                    277:                return(KERN_INVALID_ARGUMENT);
                    278: 
                    279:        vm_object_cache_lock();
                    280:        vm_object_lock(object);
                    281:        object->can_persist = should_cache;
                    282:        vm_object_unlock(object);
                    283:        vm_object_cache_unlock();
                    284: 
                    285:        vm_object_deallocate(object);
                    286: 
                    287:        return(KERN_SUCCESS);
                    288: }

unix.superglobalmegacorp.com

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