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

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:  *
1.1.1.3 ! root       36:  *     from: @(#)vm_pager.c    7.4 (Berkeley) 5/7/91
        !            37:  *     vm_pager.c,v 1.4.2.1 1993/07/24 21:34:02 cgd Exp
1.1       root       38:  *
                     39:  *
                     40:  * Copyright (c) 1987, 1990 Carnegie-Mellon University.
                     41:  * All rights reserved.
                     42:  *
                     43:  * Authors: Avadis Tevanian, Jr., Michael Wayne Young
                     44:  * 
                     45:  * Permission to use, copy, modify and distribute this software and
                     46:  * its documentation is hereby granted, provided that both the copyright
                     47:  * notice and this permission notice appear in all copies of the
                     48:  * software, derivative works or modified versions, and any portions
                     49:  * thereof, and that both notices appear in supporting documentation.
                     50:  * 
                     51:  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 
                     52:  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND 
                     53:  * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
                     54:  * 
                     55:  * Carnegie Mellon requests users of this software to return to
                     56:  *
                     57:  *  Software Distribution Coordinator  or  [email protected]
                     58:  *  School of Computer Science
                     59:  *  Carnegie Mellon University
                     60:  *  Pittsburgh PA 15213-3890
                     61:  *
                     62:  * any improvements or extensions that they make and grant Carnegie the
                     63:  * rights to redistribute these changes.
                     64:  */
                     65: 
                     66: /*
                     67:  *     Paging space routine stubs.  Emulates a matchmaker-like interface
                     68:  *     for builtin pagers.
                     69:  */
                     70: 
                     71: #include "param.h"
                     72: #include "malloc.h"
                     73: 
                     74: #include "vm.h"
                     75: #include "vm_page.h"
                     76: #include "vm_kern.h"
                     77: 
                     78: #include "swappager.h"
                     79: #if NSWAPPAGER > 0
                     80: extern struct pagerops swappagerops;
                     81: #endif
                     82: #include "vnodepager.h"
                     83: #if NVNODEPAGER > 0
                     84: extern struct pagerops vnodepagerops;
                     85: #endif
                     86: #include "devpager.h"
                     87: #if NDEVPAGER > 0
                     88: extern struct pagerops devicepagerops;
                     89: #endif
                     90: 
                     91: struct pagerops *pagertab[] = {
1.1.1.3 ! root       92: #if NSWAPPAGER > 0
1.1       root       93:        &swappagerops,          /* PG_SWAP */
1.1.1.3 ! root       94: #else
        !            95:        NULL,                   /* no swappager */
        !            96: #endif
        !            97: #if NVNODEPAGER > 0
1.1       root       98:        &vnodepagerops,         /* PG_VNODE */
1.1.1.3 ! root       99: #else
        !           100:        NULL,                   /* no vnodepager */
        !           101: #endif
        !           102: #if NDEVPAGER > 0
1.1       root      103:        &devicepagerops,        /* PG_DEV */
1.1.1.3 ! root      104: #else
        !           105:        NULL,                   /* no devpager */
        !           106: #endif
1.1       root      107: };
                    108: int npagers = sizeof (pagertab) / sizeof (pagertab[0]);
                    109: 
                    110: struct pagerops *dfltpagerops = NULL;  /* default pager */
                    111: 
                    112: /*
                    113:  * Kernel address space for mapping pages.
                    114:  * Used by pagers where KVAs are needed for IO.
                    115:  */
                    116: #define PAGER_MAP_SIZE (256 * PAGE_SIZE)
                    117: vm_map_t pager_map;
                    118: vm_offset_t pager_sva, pager_eva;
                    119: 
                    120: void
                    121: vm_pager_init()
                    122: {
                    123:        struct pagerops **pgops;
                    124: 
                    125:        /*
                    126:         * Allocate a kernel submap for tracking get/put page mappings
                    127:         */
                    128:        pager_map = kmem_suballoc(kernel_map, &pager_sva, &pager_eva,
                    129:                                  PAGER_MAP_SIZE, FALSE);
                    130:        /*
                    131:         * Initialize known pagers
                    132:         */
                    133:        for (pgops = pagertab; pgops < &pagertab[npagers]; pgops++)
1.1.1.3 ! root      134:                if (*pgops) (*(*pgops)->pgo_init)();
1.1       root      135:        if (dfltpagerops == NULL)
                    136:                panic("no default pager");
                    137: }
                    138: 
                    139: /*
                    140:  * Allocate an instance of a pager of the given type.
                    141:  */
                    142: vm_pager_t
                    143: vm_pager_allocate(type, handle, size, prot)
                    144:        int type;
                    145:        caddr_t handle;
                    146:        vm_size_t size;
                    147:        vm_prot_t prot;
                    148: {
                    149:        vm_pager_t pager;
                    150:        struct pagerops *ops;
                    151: 
                    152:        ops = (type == PG_DFLT) ? dfltpagerops : pagertab[type];
                    153:        return((*ops->pgo_alloc)(handle, size, prot));
                    154: }
                    155: 
                    156: void
                    157: vm_pager_deallocate(pager)
                    158:        vm_pager_t      pager;
                    159: {
                    160:        if (pager == NULL)
                    161:                panic("vm_pager_deallocate: null pager");
                    162: 
                    163:        VM_PAGER_DEALLOC(pager);
                    164: }
                    165: 
                    166: vm_pager_get(pager, m, sync)
                    167:        vm_pager_t      pager;
                    168:        vm_page_t       m;
                    169:        boolean_t       sync;
                    170: {
                    171:        extern boolean_t vm_page_zero_fill();
                    172: 
                    173:        if (pager == NULL)
                    174:                return(vm_page_zero_fill(m) ? VM_PAGER_OK : VM_PAGER_FAIL);
                    175:        return(VM_PAGER_GET(pager, m, sync));
                    176: }
                    177: 
                    178: vm_pager_put(pager, m, sync)
                    179:        vm_pager_t      pager;
                    180:        vm_page_t       m;
                    181:        boolean_t       sync;
                    182: {
                    183:        if (pager == NULL)
                    184:                panic("vm_pager_put: null pager");
                    185:        return(VM_PAGER_PUT(pager, m, sync));
                    186: }
                    187: 
                    188: boolean_t
                    189: vm_pager_has_page(pager, offset)
                    190:        vm_pager_t      pager;
                    191:        vm_offset_t     offset;
                    192: {
                    193:        if (pager == NULL)
                    194:                panic("vm_pager_has_page");
                    195:        return(VM_PAGER_HASPAGE(pager, offset));
                    196: }
                    197: 
                    198: /*
                    199:  * Called by pageout daemon before going back to sleep.
                    200:  * Gives pagers a chance to clean up any completed async pageing operations.
                    201:  */
                    202: void
                    203: vm_pager_sync()
                    204: {
                    205:        struct pagerops **pgops;
                    206: 
                    207:        for (pgops = pagertab; pgops < &pagertab[npagers]; pgops++)
1.1.1.3 ! root      208:                if (*pgops) (*(*pgops)->pgo_putpage)(NULL, NULL, FALSE);
1.1       root      209: }
                    210: 
                    211: vm_offset_t
                    212: vm_pager_map_page(m)
                    213:        vm_page_t       m;
                    214: {
                    215:        vm_offset_t kva;
                    216: 
                    217: #ifdef DEBUG
                    218:        if (!m->busy || m->active)
                    219:                panic("vm_pager_map_page: page active or not busy");
                    220:        if (m->pagerowned)
                    221:                printf("vm_pager_map_page: page %x already in pager\n", m);
                    222: #endif
                    223:        kva = kmem_alloc_wait(pager_map, PAGE_SIZE);
                    224: #ifdef DEBUG
                    225:        m->pagerowned = 1;
                    226: #endif
                    227:        pmap_enter(vm_map_pmap(pager_map), kva, VM_PAGE_TO_PHYS(m),
                    228:                   VM_PROT_DEFAULT, TRUE);
                    229:        return(kva);
                    230: }
                    231: 
                    232: void
                    233: vm_pager_unmap_page(kva)
                    234:        vm_offset_t     kva;
                    235: {
                    236: #ifdef DEBUG
                    237:        vm_page_t m;
                    238: 
                    239:        m = PHYS_TO_VM_PAGE(pmap_extract(vm_map_pmap(pager_map), kva));
                    240: #endif
                    241:        kmem_free_wakeup(pager_map, kva, PAGE_SIZE);
                    242: #ifdef DEBUG
                    243:        if (m->pagerowned)
                    244:                m->pagerowned = 0;
                    245:        else
                    246:                printf("vm_pager_unmap_page: page %x(%x/%x) not owned\n",
                    247:                       m, kva, VM_PAGE_TO_PHYS(m));
                    248: #endif
                    249: }
                    250: 
                    251: vm_pager_t
                    252: vm_pager_lookup(list, handle)
                    253:        register queue_head_t *list;
                    254:        caddr_t handle;
                    255: {
                    256:        register vm_pager_t pager;
                    257: 
                    258:        pager = (vm_pager_t) queue_first(list);
                    259:        while (!queue_end(list, (queue_entry_t)pager)) {
                    260:                if (pager->pg_handle == handle)
                    261:                        return(pager);
                    262:                pager = (vm_pager_t) queue_next(&pager->pg_list);
                    263:        }
                    264:        return(NULL);
                    265: }
                    266: 
                    267: /*
                    268:  * This routine gains a reference to the object.
                    269:  * Explicit deallocation is necessary.
                    270:  */
                    271: pager_cache(object, should_cache)
                    272:        vm_object_t     object;
                    273:        boolean_t       should_cache;
                    274: {
                    275:        if (object == NULL)
                    276:                return(KERN_INVALID_ARGUMENT);
                    277: 
                    278:        vm_object_cache_lock();
                    279:        vm_object_lock(object);
                    280:        object->can_persist = should_cache;
                    281:        vm_object_unlock(object);
                    282:        vm_object_cache_unlock();
                    283: 
                    284:        vm_object_deallocate(object);
                    285: 
                    286:        return(KERN_SUCCESS);
                    287: }

unix.superglobalmegacorp.com

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