Annotation of kernel/vm/vm_page.h, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
        !             3:  *
        !             4:  * @APPLE_LICENSE_HEADER_START@
        !             5:  * 
        !             6:  * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
        !             7:  * Reserved.  This file contains Original Code and/or Modifications of
        !             8:  * Original Code as defined in and that are subject to the Apple Public
        !             9:  * Source License Version 1.1 (the "License").  You may not use this file
        !            10:  * except in compliance with the License.  Please obtain a copy of the
        !            11:  * License at http://www.apple.com/publicsource and read it before using
        !            12:  * this file.
        !            13:  * 
        !            14:  * The Original Code and all software distributed under the License are
        !            15:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
        !            16:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
        !            17:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
        !            18:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
        !            19:  * License for the specific language governing rights and limitations
        !            20:  * under the License.
        !            21:  * 
        !            22:  * @APPLE_LICENSE_HEADER_END@
        !            23:  */
        !            24: 
        !            25: /* 
        !            26:  * Mach Operating System
        !            27:  * Copyright (c) 1993-1988 Carnegie Mellon University
        !            28:  * All Rights Reserved.
        !            29:  * 
        !            30:  * Permission to use, copy, modify and distribute this software and its
        !            31:  * documentation is hereby granted, provided that both the copyright
        !            32:  * notice and this permission notice appear in all copies of the
        !            33:  * software, derivative works or modified versions, and any portions
        !            34:  * thereof, and that both notices appear in supporting documentation.
        !            35:  * 
        !            36:  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
        !            37:  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
        !            38:  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
        !            39:  * 
        !            40:  * Carnegie Mellon requests users of this software to return to
        !            41:  * 
        !            42:  *  Software Distribution Coordinator  or  [email protected]
        !            43:  *  School of Computer Science
        !            44:  *  Carnegie Mellon University
        !            45:  *  Pittsburgh PA 15213-3890
        !            46:  * 
        !            47:  * any improvements or extensions that they make and grant Carnegie Mellon
        !            48:  * the rights to redistribute these changes.
        !            49:  */
        !            50: /*
        !            51:  *     File:   vm/vm_page.h
        !            52:  *     Author: Avadis Tevanian, Jr., Michael Wayne Young
        !            53:  *     Date:   1985
        !            54:  *
        !            55:  *     Resident memory system definitions.
        !            56:  */
        !            57: 
        !            58: #ifndef        _VM_VM_PAGE_H_
        !            59: #define _VM_VM_PAGE_H_
        !            60: 
        !            61: #import <mach/features.h>
        !            62: 
        !            63: #include <mach/boolean.h>
        !            64: #include <mach/vm_prot.h>
        !            65: #include <mach/vm_param.h>
        !            66: #include <vm/vm_object.h>
        !            67: #include <kern/queue.h>
        !            68: #include <kern/lock.h>
        !            69: #include <kern/zalloc.h>
        !            70: 
        !            71: #include <kern/macro_help.h>
        !            72: #include <kern/sched_prim.h>   /* definitions of wait/wakeup */
        !            73: 
        !            74: #if    MACH_VM_DEBUG
        !            75: #include <mach_debug/hash_info.h>
        !            76: #endif
        !            77: 
        !            78: /*
        !            79:  *     Management of resident (logical) pages.
        !            80:  *
        !            81:  *     A small structure is kept for each resident
        !            82:  *     page, indexed by page number.  Each structure
        !            83:  *     is an element of several lists:
        !            84:  *
        !            85:  *             A hash table bucket used to quickly
        !            86:  *             perform object/offset lookups
        !            87:  *
        !            88:  *             A list of all pages for a given object,
        !            89:  *             so they can be quickly deactivated at
        !            90:  *             time of deallocation.
        !            91:  *
        !            92:  *             An ordered list of pages due for pageout.
        !            93:  *
        !            94:  *     In addition, the structure contains the object
        !            95:  *     and offset to which this page belongs (for pageout),
        !            96:  *     and sundry status bits.
        !            97:  *
        !            98:  *     Fields in this structure are locked either by the lock on the
        !            99:  *     object that the page belongs to (O) or by the lock on the page
        !           100:  *     queues (P).  [Some fields require that both locks be held to
        !           101:  *     change that field; holding either lock is sufficient to read.]
        !           102:  */
        !           103: 
        !           104: struct vm_page {
        !           105:        queue_chain_t   pageq;          /* queue info for FIFO
        !           106:                                         * queue or free list (P) */
        !           107:        queue_chain_t   listq;          /* all pages in same object (O) */
        !           108:        struct vm_page  *next;          /* VP bucket link (O) */
        !           109: 
        !           110:        vm_object_t     object;         /* which object am I in (O,P) */
        !           111:        vm_offset_t     offset;         /* offset into that object (O,P) */
        !           112: 
        !           113:        unsigned int    wire_count:16,  /* how many wired down maps use me?
        !           114:                                           (O&P) */
        !           115:        /* boolean_t */ inactive:1,     /* page is in inactive list (P) */
        !           116:                        active:1,       /* page is in active list (P) */
        !           117:                        laundry:1,      /* page is being cleaned now (P)*/
        !           118:                        free:1,         /* page is on free list (P) */
        !           119:                        reference:1,    /* page has been used (P) */
        !           120: #if    OLD_VM_CODE
        !           121:                        clean:1,        /* page has not been modified (P) */
        !           122: #endif
        !           123:                        :0;             /* (force to 'long' boundary) */
        !           124: 
        !           125:        unsigned int
        !           126:        /* boolean_t */ busy:1,         /* page is in transit (O) */
        !           127:                        wanted:1,       /* someone is waiting for page (O) */
        !           128:                        tabled:1,       /* page is in VP table (O) */
        !           129:                        fictitious:1,   /* Physical page doesn't exist (O) */
        !           130:                        private:1,      /* Page should not be returned to
        !           131:                                         *  the free list (O) */
        !           132:                        absent:1,       /* Data has been requested, but is
        !           133:                                         *  not yet available (O) */
        !           134:                        error:1,        /* Data manager was unable to provide
        !           135:                                         *  data due to error (O) */
        !           136:                        dirty:1,        /* Page must be cleaned (O) */
        !           137:                        precious:1,     /* Page is precious; data must be
        !           138:                                         *  returned even if clean (O) */
        !           139:                        overwriting:1,  /* Request to unlock has been made
        !           140:                                         * without having data. (O)
        !           141:                                         * [See vm_object_overwrite] */
        !           142: #if    OLD_VM_CODE
        !           143:                        copy_on_write:1,/* Page must be copied before being
        !           144:                                         * changed (O) */
        !           145:                        nfspagereq:1,   /* NFS pagein request (O) */
        !           146:                        asyncrw:1,      /* Async read/write */
        !           147: #endif
        !           148:                        :0;
        !           149: 
        !           150:        vm_offset_t     phys_addr;      /* Physical address of page, passed
        !           151:                                         *  to pmap_enter (read-only) */
        !           152:        vm_prot_t       page_lock;      /* Uses prohibited by data manager (O) */
        !           153:        vm_prot_t       unlock_request; /* Outstanding unlock request (O) */
        !           154: };
        !           155: 
        !           156: typedef struct vm_page *vm_page_t;
        !           157: 
        !           158: #define VM_PAGE_NULL           ((vm_page_t) 0)
        !           159: 
        !           160: /*
        !           161:  *     For debugging, this macro can be defined to perform
        !           162:  *     some useful check on a page structure.
        !           163:  */
        !           164: 
        !           165: #define VM_PAGE_CHECK(mem)
        !           166: 
        !           167: /*
        !           168:  *     Each pageable resident page falls into one of three lists:
        !           169:  *
        !           170:  *     free    
        !           171:  *             Available for allocation now.
        !           172:  *     inactive
        !           173:  *             Not referenced in any map, but still has an
        !           174:  *             object/offset-page mapping, and may be dirty.
        !           175:  *             This is the list of pages that should be
        !           176:  *             paged out next.
        !           177:  *     active
        !           178:  *             A list of pages which have been placed in
        !           179:  *             at least one physical map.  This list is
        !           180:  *             ordered, in LRU-like fashion.
        !           181:  */
        !           182: 
        !           183: #if    OLD_VM_CODE
        !           184: extern
        !           185: queue_head_t   vm_page_queue_free;     /* memory free queue */
        !           186: #else
        !           187: extern
        !           188: vm_page_t      vm_page_queue_free;     /* memory free queue */
        !           189: extern
        !           190: vm_page_t      vm_page_queue_fictitious;       /* fictitious free queue */
        !           191: #endif
        !           192: extern
        !           193: queue_head_t   vm_page_queue_active;   /* active memory queue */
        !           194: extern
        !           195: queue_head_t   vm_page_queue_inactive; /* inactive memory queue */
        !           196: 
        !           197: extern
        !           198: vm_offset_t    first_phys_addr;        /* physical address for first_page */
        !           199: extern
        !           200: vm_offset_t    last_phys_addr;         /* physical address for last_page */
        !           201: 
        !           202: extern
        !           203: int    vm_page_free_count;     /* How many pages are free? */
        !           204: extern
        !           205: int    vm_page_fictitious_count;/* How many fictitious pages are free? */
        !           206: extern
        !           207: int    vm_page_active_count;   /* How many pages are active? */
        !           208: extern
        !           209: int    vm_page_inactive_count; /* How many pages are inactive? */
        !           210: extern
        !           211: int    vm_page_wire_count;     /* How many pages are wired? */
        !           212: extern
        !           213: int    vm_page_free_target;    /* How many do we want free? */
        !           214: extern
        !           215: int    vm_page_free_min;       /* When to wakeup pageout */
        !           216: extern
        !           217: int    vm_page_inactive_target;/* How many do we want inactive? */
        !           218: extern
        !           219: int    vm_page_free_reserved;  /* How many pages reserved to do pageout */
        !           220: extern
        !           221: int    vm_page_laundry_count;  /* How many pages being laundered? */
        !           222: #if    OLD_VM_CODE
        !           223: extern
        !           224: int    vm_page_inactive_target_min;/* Inactive low water mark (floor) */
        !           225: 
        !           226: #define VM_PAGE_TO_PHYS(entry) ((entry)->phys_addr)
        !           227: 
        !           228: #define IS_VM_PHYSADDR(pa)     (vm_valid_page(pa))
        !           229: 
        !           230: #define PHYS_TO_VM_PAGE(pa)    (vm_phys_to_vm_page(pa))
        !           231: #endif
        !           232: 
        !           233: decl_simple_lock_data(extern,vm_page_queue_lock)/* lock on active and inactive
        !           234:                                                   page queues */
        !           235: decl_simple_lock_data(extern,vm_page_queue_free_lock)
        !           236:                                                /* lock on free page queue */
        !           237: 
        !           238: #if    OLD_VM_CODE
        !           239: vm_offset_t    vm_page_startup();
        !           240: vm_page_t      vm_page_lookup(vm_object_t, vm_offset_t);
        !           241: vm_page_t      vm_page_alloc(vm_object_t, vm_offset_t);
        !           242: void           vm_page_init(vm_page_t, vm_object_t, vm_offset_t, vm_offset_t);
        !           243: void           vm_page_free(vm_page_t);
        !           244: void           vm_page_addfree(vm_page_t);
        !           245: void           vm_page_activate(vm_page_t);
        !           246: void           vm_page_deactivate(vm_page_t);
        !           247: void           vm_page_rename(vm_page_t, vm_object_t, vm_offset_t);
        !           248: void           vm_page_insert(vm_page_t, vm_object_t, vm_offset_t);
        !           249: void           vm_page_remove(vm_page_t);
        !           250: 
        !           251: boolean_t      vm_page_zero_fill(vm_page_t);
        !           252: void           vm_page_copy(vm_page_t, vm_page_t);
        !           253: 
        !           254: void           vm_page_wire(vm_page_t);
        !           255: void           vm_page_unwire(vm_page_t);
        !           256: 
        !           257: void           vm_set_page_size();
        !           258: #else
        !           259: extern unsigned int    vm_page_free_wanted;
        !           260:                                /* how many threads are waiting for memory */
        !           261: 
        !           262: extern vm_offset_t     vm_page_fictitious_addr;
        !           263:                                /* (fake) phys_addr of fictitious pages */
        !           264: 
        !           265: extern void            vm_page_bootstrap(
        !           266:        vm_offset_t     *startp,
        !           267:        vm_offset_t     *endp);
        !           268: extern void            vm_page_module_init(void);
        !           269: 
        !           270: extern void            vm_page_create(
        !           271:        vm_offset_t     start,
        !           272:        vm_offset_t     end);
        !           273: extern vm_page_t       vm_page_lookup(
        !           274:        vm_object_t     object,
        !           275:        vm_offset_t     offset);
        !           276: extern vm_page_t       vm_page_grab_fictitious(void);
        !           277: extern void            vm_page_release_fictitious(vm_page_t);
        !           278: extern boolean_t       vm_page_convert(vm_page_t);
        !           279: extern void            vm_page_more_fictitious(void);
        !           280: extern vm_page_t       vm_page_grab(void);
        !           281: extern void            vm_page_release(vm_page_t);
        !           282: extern void            vm_page_wait(void (*)(void));
        !           283: extern vm_page_t       vm_page_alloc(
        !           284:        vm_object_t     object,
        !           285:        vm_offset_t     offset);
        !           286: extern void            vm_page_init(
        !           287:        vm_page_t       mem,
        !           288:        vm_offset_t     phys_addr);
        !           289: extern void            vm_page_free(vm_page_t);
        !           290: extern void            vm_page_activate(vm_page_t);
        !           291: extern void            vm_page_deactivate(vm_page_t);
        !           292: extern void            vm_page_rename(
        !           293:        vm_page_t       mem,
        !           294:        vm_object_t     new_object,
        !           295:        vm_offset_t     new_offset);
        !           296: extern void            vm_page_insert(
        !           297:        vm_page_t       mem,
        !           298:        vm_object_t     object,
        !           299:        vm_offset_t     offset);
        !           300: extern void            vm_page_remove(
        !           301:        vm_page_t       mem);
        !           302: 
        !           303: extern void            vm_page_zero_fill(vm_page_t);
        !           304: extern void            vm_page_copy(vm_page_t src_m, vm_page_t dest_m);
        !           305: 
        !           306: extern void            vm_page_wire(vm_page_t);
        !           307: extern void            vm_page_unwire(vm_page_t);
        !           308: 
        !           309: extern void            vm_set_page_size(void);
        !           310: 
        !           311: #if    MACH_VM_DEBUG
        !           312: extern unsigned int    vm_page_info(
        !           313:        hash_info_bucket_t      *info,
        !           314:        unsigned int            count);
        !           315: #endif
        !           316: #endif
        !           317: 
        !           318: /*
        !           319:  *     Functions implemented as macros
        !           320:  */
        !           321: 
        !           322: #if    OLD_VM_CODE
        !           323: #import <kern/sched_prim.h>    /* definitions of wait/wakeup */
        !           324: 
        !           325: #define PAGE_ASSERT_WAIT(m, interruptible)     { \
        !           326:                                (m)->wanted = TRUE; \
        !           327:                                assert_wait((m), (interruptible)); \
        !           328:                        }
        !           329: 
        !           330: #define PAGE_WAKEUP(m) { \
        !           331:                                (m)->busy = FALSE; \
        !           332:                                if ((m)->wanted) { \
        !           333:                                        (m)->wanted = FALSE; \
        !           334:                                        thread_wakeup((m)); \
        !           335:                                } \
        !           336:                        }
        !           337: 
        !           338: #define        VM_PAGE_FREE(p) { \
        !           339:                vm_page_lock_queues();          \
        !           340:                vm_page_free(p);                \
        !           341:                vm_page_unlock_queues();        \
        !           342: }
        !           343: #else
        !           344: #define PAGE_ASSERT_WAIT(m, interruptible)                     \
        !           345:                MACRO_BEGIN                                     \
        !           346:                (m)->wanted = TRUE;                             \
        !           347:                assert_wait((event_t) (m), (interruptible));    \
        !           348:                MACRO_END
        !           349: 
        !           350: #define PAGE_WAKEUP_DONE(m)                                    \
        !           351:                MACRO_BEGIN                                     \
        !           352:                (m)->busy = FALSE;                              \
        !           353:                if ((m)->wanted) {                              \
        !           354:                        (m)->wanted = FALSE;                    \
        !           355:                        thread_wakeup(((event_t) m));           \
        !           356:                }                                               \
        !           357:                MACRO_END
        !           358: 
        !           359: #define PAGE_WAKEUP(m)                                         \
        !           360:                MACRO_BEGIN                                     \
        !           361:                if ((m)->wanted) {                              \
        !           362:                        (m)->wanted = FALSE;                    \
        !           363:                        thread_wakeup((event_t) (m));           \
        !           364:                }                                               \
        !           365:                MACRO_END
        !           366: 
        !           367: #define VM_PAGE_FREE(p)                        \
        !           368:                MACRO_BEGIN                     \
        !           369:                vm_page_lock_queues();          \
        !           370:                vm_page_free(p);                \
        !           371:                vm_page_unlock_queues();        \
        !           372:                MACRO_END
        !           373: #endif
        !           374: 
        !           375: /*
        !           376:  *     Macro to be used in place of pmap_enter()
        !           377:  */
        !           378: 
        !           379: #define PMAP_ENTER(pmap, virtual_address, page, protection, wired) \
        !           380:                MACRO_BEGIN                                     \
        !           381:                pmap_enter(                                     \
        !           382:                        (pmap),                                 \
        !           383:                        (virtual_address),                      \
        !           384:                        (page)->phys_addr,                      \
        !           385:                        (protection) & ~(page)->page_lock,      \
        !           386:                        (wired)                                 \
        !           387:                 );                                             \
        !           388:                MACRO_END
        !           389: 
        !           390: #define        VM_PAGE_WAIT(continuation)      vm_page_wait(continuation)
        !           391: 
        !           392: #define vm_page_lock_queues()  simple_lock(&vm_page_queue_lock)
        !           393: #define vm_page_unlock_queues()        simple_unlock(&vm_page_queue_lock)
        !           394: 
        !           395: #define VM_PAGE_QUEUES_REMOVE(mem)                             \
        !           396:        MACRO_BEGIN                                             \
        !           397:        if (mem->active) {                                      \
        !           398:                queue_remove(&vm_page_queue_active,             \
        !           399:                        mem, vm_page_t, pageq);                 \
        !           400:                mem->active = FALSE;                            \
        !           401:                vm_page_active_count--;                         \
        !           402:        }                                                       \
        !           403:                                                                \
        !           404:        if (mem->inactive) {                                    \
        !           405:                queue_remove(&vm_page_queue_inactive,           \
        !           406:                        mem, vm_page_t, pageq);                 \
        !           407:                mem->inactive = FALSE;                          \
        !           408:                vm_page_inactive_count--;                       \
        !           409:        }                                                       \
        !           410:        MACRO_END
        !           411: 
        !           412: #if    OLD_VM_CODE
        !           413: vm_page_t vm_page_alloc_sequential(vm_object_t, vm_offset_t, boolean_t);
        !           414: #define        vm_page_alloc(object, offset)           \
        !           415:        vm_page_alloc_sequential(object,offset,TRUE)
        !           416: boolean_t vm_page_completeio();
        !           417: #define vm_page_set_modified(m)        { (m)->clean = FALSE; }
        !           418: #endif
        !           419: 
        !           420: #endif /* _VM_VM_PAGE_H_ */

unix.superglobalmegacorp.com

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