Annotation of XNU/osfmk/vm/vm_page.h, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
                      3:  *
                      4:  * @APPLE_LICENSE_HEADER_START@
                      5:  * 
                      6:  * The contents of this file constitute Original Code as defined in and
                      7:  * are subject to the Apple Public Source License Version 1.1 (the
                      8:  * "License").  You may not use this file except in compliance with the
                      9:  * License.  Please obtain a copy of the License at
                     10:  * http://www.apple.com/publicsource and read it before using this file.
                     11:  * 
                     12:  * This Original Code and all software distributed under the License are
                     13:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
                     14:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
                     15:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
                     16:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
                     17:  * License for the specific language governing rights and limitations
                     18:  * under the License.
                     19:  * 
                     20:  * @APPLE_LICENSE_HEADER_END@
                     21:  */
                     22: /*
                     23:  * @OSF_COPYRIGHT@
                     24:  */
                     25: /* 
                     26:  * Mach Operating System
                     27:  * Copyright (c) 1991,1990,1989,1988 Carnegie Mellon University
                     28:  * All Rights Reserved.
                     29:  * 
                     30:  * Permission to use, copy, modify and distribute this software and its
                     31:  * documentation is hereby granted, provided that both the copyright
                     32:  * notice and this permission notice appear in all copies of the
                     33:  * software, derivative works or modified versions, and any portions
                     34:  * thereof, and that both notices appear in supporting documentation.
                     35:  * 
                     36:  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
                     37:  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
                     38:  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
                     39:  * 
                     40:  * Carnegie Mellon requests users of this software to return to
                     41:  * 
                     42:  *  Software Distribution Coordinator  or  [email protected]
                     43:  *  School of Computer Science
                     44:  *  Carnegie Mellon University
                     45:  *  Pittsburgh PA 15213-3890
                     46:  * 
                     47:  * any improvements or extensions that they make and grant Carnegie Mellon
                     48:  * the rights to redistribute these changes.
                     49:  */
                     50: /*
                     51:  */
                     52: /*
                     53:  *     File:   vm/vm_page.h
                     54:  *     Author: Avadis Tevanian, Jr., Michael Wayne Young
                     55:  *     Date:   1985
                     56:  *
                     57:  *     Resident memory system definitions.
                     58:  */
                     59: 
                     60: #ifndef        _VM_VM_PAGE_H_
                     61: #define _VM_VM_PAGE_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: 
                     70: #include <kern/macro_help.h>
                     71: 
                     72: /*
                     73:  *     Management of resident (logical) pages.
                     74:  *
                     75:  *     A small structure is kept for each resident
                     76:  *     page, indexed by page number.  Each structure
                     77:  *     is an element of several lists:
                     78:  *
                     79:  *             A hash table bucket used to quickly
                     80:  *             perform object/offset lookups
                     81:  *
                     82:  *             A list of all pages for a given object,
                     83:  *             so they can be quickly deactivated at
                     84:  *             time of deallocation.
                     85:  *
                     86:  *             An ordered list of pages due for pageout.
                     87:  *
                     88:  *     In addition, the structure contains the object
                     89:  *     and offset to which this page belongs (for pageout),
                     90:  *     and sundry status bits.
                     91:  *
                     92:  *     Fields in this structure are locked either by the lock on the
                     93:  *     object that the page belongs to (O) or by the lock on the page
                     94:  *     queues (P).  [Some fields require that both locks be held to
                     95:  *     change that field; holding either lock is sufficient to read.]
                     96:  */
                     97: 
                     98: struct vm_page {
                     99:        queue_chain_t   pageq;          /* queue info for FIFO
                    100:                                         * queue or free list (P) */
                    101:        queue_chain_t   listq;          /* all pages in same object (O) */
                    102:        struct vm_page  *next;          /* VP bucket link (O) */
                    103: 
                    104:        vm_object_t     object;         /* which object am I in (O&P) */
                    105:        vm_offset_t     offset;         /* offset into that object (O,P) */
                    106: 
                    107:        unsigned int    wire_count:16,  /* how many wired down maps use me?
                    108:                                           (O&P) */
                    109:        /* boolean_t */ inactive:1,     /* page is in inactive list (P) */
                    110:                        active:1,       /* page is in active list (P) */
                    111:                        laundry:1,      /* page is being cleaned now (P)*/
                    112:                        free:1,         /* page is on free list (P) */
                    113:                        reference:1,    /* page has been used (P) */
                    114:                        limbo:1,        /* page prepped then stolen (P) */
                    115:                        pageout:1,      /* page wired & busy for pageout (P) */
                    116:                        gobbled:1,      /* page used internally (P) */
                    117:                        :0;             /* (force to 'long' boundary) */
                    118: #ifdef ns32000
                    119:        int             pad;            /* extra space for ns32000 bit ops */
                    120: #endif /* ns32000 */
                    121: 
                    122:        unsigned int
                    123:        /* boolean_t */ busy:1,         /* page is in transit (O) */
                    124:                        wanted:1,       /* someone is waiting for page (O) */
                    125:                        tabled:1,       /* page is in VP table (O) */
                    126:                        fictitious:1,   /* Physical page doesn't exist (O) */
                    127:                        private:1,      /* Page should not be returned to
                    128:                                         *  the free list (O) */
                    129:                        absent:1,       /* Data has been requested, but is
                    130:                                         *  not yet available (O) */
                    131:                        error:1,        /* Data manager was unable to provide
                    132:                                         *  data due to error (O) */
                    133:                        dirty:1,        /* Page must be cleaned (O) */
                    134:                        cleaning:1,     /* Page clean has begun (O) */
                    135:                        precious:1,     /* Page is precious; data must be
                    136:                                         *  returned even if clean (O) */
                    137:                        clustered:1,    /* page is not the faulted page (O) */
                    138:                        overwriting:1,  /* Request to unlock has been made
                    139:                                         * without having data. (O)
                    140:                                         * [See vm_fault_page_overwrite] */
                    141:                        restart:1,      /* Page was pushed higher in shadow
                    142:                                           chain by copy_call-related pagers;
                    143:                                           start again at top of chain */
                    144:                        lock_supplied:1,/* protection supplied by pager (O) */
                    145:        /* vm_prot_t */ page_lock:3,    /* Uses prohibited by pager (O) */
                    146:        /* vm_prot_t */ unlock_request:3,/* Outstanding unlock request (O) */
                    147:                        unusual:1,      /* Page is absent, error, restart or
                    148:                                           page locked */
                    149:                        discard_request:1,/* a memory_object_discard_request()
                    150:                                           * has been sent */
                    151:                        list_req_pending:1, /* pagein/pageout alt mechanism */
                    152:                                            /* allows creation of list      */
                    153:                                            /* requests on pages that are   */
                    154:                                            /* actively being paged.        */
                    155:                        :0;
                    156: 
                    157:        vm_offset_t     phys_addr;      /* Physical address of page, passed
                    158:                                         *  to pmap_enter (read-only) */
                    159:        kern_return_t   page_error;
                    160: 
                    161:        union {
                    162:          struct {
                    163:           unsigned int prep:16,        /* page prep count */
                    164:                        pin:16;         /* page pin pount */
                    165:          } pp_counts;
                    166:          unsigned int  pp_both;        /* used to test for both zero */
                    167:        } prep_pin_u;
                    168: };
                    169: 
                    170: typedef struct vm_page *vm_page_t;
                    171: 
                    172: #define prep_count     prep_pin_u.pp_counts.prep
                    173: #define pin_count      prep_pin_u.pp_counts.pin
                    174: #define prep_pin_count prep_pin_u.pp_both
                    175: 
                    176: #define VM_PAGE_NULL           ((vm_page_t) 0)
                    177: #define NEXT_PAGE(m)    ((vm_page_t) (m)->pageq.next)
                    178: 
                    179: /*
                    180:  * XXX The unusual bit should not be necessary.  Most of the bit
                    181:  * XXX fields above really want to be masks.
                    182:  */
                    183: 
                    184: /*
                    185:  *     For debugging, this macro can be defined to perform
                    186:  *     some useful check on a page structure.
                    187:  */
                    188: 
                    189: #define VM_PAGE_CHECK(mem)
                    190: 
                    191: /*
                    192:  *     Each pageable resident page falls into one of three lists:
                    193:  *
                    194:  *     free    
                    195:  *             Available for allocation now.
                    196:  *     inactive
                    197:  *             Not referenced in any map, but still has an
                    198:  *             object/offset-page mapping, and may be dirty.
                    199:  *             This is the list of pages that should be
                    200:  *             paged out next.
                    201:  *     active
                    202:  *             A list of pages which have been placed in
                    203:  *             at least one physical map.  This list is
                    204:  *             ordered, in LRU-like fashion.
                    205:  */
                    206: 
                    207: extern
                    208: vm_page_t      vm_page_queue_free;     /* memory free queue */
                    209: extern
                    210: vm_page_t      vm_page_queue_fictitious;       /* fictitious free queue */
                    211: extern
                    212: queue_head_t   vm_page_queue_active;   /* active memory queue */
                    213: extern
                    214: queue_head_t   vm_page_queue_inactive; /* inactive memory queue */
                    215: 
                    216: extern
                    217: vm_offset_t    first_phys_addr;        /* physical address for first_page */
                    218: extern
                    219: vm_offset_t    last_phys_addr;         /* physical address for last_page */
                    220: 
                    221: extern
                    222: int    vm_page_free_count;     /* How many pages are free? */
                    223: extern
                    224: int    vm_page_fictitious_count;/* How many fictitious pages are free? */
                    225: extern
                    226: int    vm_page_active_count;   /* How many pages are active? */
                    227: extern
                    228: int    vm_page_inactive_count; /* How many pages are inactive? */
                    229: extern
                    230: int    vm_page_wire_count;     /* How many pages are wired? */
                    231: extern
                    232: int    vm_page_free_target;    /* How many do we want free? */
                    233: extern
                    234: int    vm_page_free_min;       /* When to wakeup pageout */
                    235: extern
                    236: int    vm_page_inactive_target;/* How many do we want inactive? */
                    237: extern
                    238: int    vm_page_free_reserved;  /* How many pages reserved to do pageout */
                    239: extern
                    240: int    vm_page_laundry_count;  /* How many pages being laundered? */
                    241: 
                    242: decl_mutex_data(,vm_page_queue_lock)
                    243:                                /* lock on active and inactive page queues */
                    244: decl_mutex_data(,vm_page_queue_free_lock)
                    245:                                /* lock on free page queue */
                    246: decl_simple_lock_data(extern,vm_page_preppin_lock)     /* lock for prep/pin */
                    247: 
                    248: extern unsigned int    vm_page_free_wanted;
                    249:                                /* how many threads are waiting for memory */
                    250: 
                    251: extern vm_offset_t     vm_page_fictitious_addr;
                    252:                                /* (fake) phys_addr of fictitious pages */
                    253: 
                    254: /*
                    255:  * Prototypes for functions exported by this module.
                    256:  */
                    257: extern void            vm_page_bootstrap(
                    258:                                        vm_offset_t     *startp,
                    259:                                        vm_offset_t     *endp);
                    260: 
                    261: extern void            vm_page_module_init(void);
                    262: 
                    263: extern void            vm_page_create(
                    264:                                        vm_offset_t     start,
                    265:                                        vm_offset_t     end);
                    266: 
                    267: extern vm_page_t       vm_page_lookup(
                    268:                                        vm_object_t     object,
                    269:                                        vm_offset_t     offset);
                    270: 
                    271: extern vm_page_t       vm_page_grab_fictitious(void);
                    272: 
                    273: extern void            vm_page_release_fictitious(
                    274:                                        vm_page_t page);
                    275: 
                    276: extern boolean_t       vm_page_convert(
                    277:                                        vm_page_t       page);
                    278: 
                    279: extern void            vm_page_more_fictitious(void);
                    280: 
                    281: extern int             vm_pool_low(void);
                    282: 
                    283: extern vm_page_t       vm_page_grab(void);
                    284: 
                    285: extern void            vm_page_release(
                    286:                                        vm_page_t       page);
                    287: 
                    288: extern void            vm_page_release_limbo(
                    289:                                        vm_page_t       page);
                    290: 
                    291: extern void            vm_page_limbo_exchange(
                    292:                                        vm_page_t       limbo_m,
                    293:                                        vm_page_t       new_m);
                    294: 
                    295: extern void            vm_page_wait( void );
                    296: 
                    297: extern vm_page_t       vm_page_alloc(
                    298:                                        vm_object_t     object,
                    299:                                        vm_offset_t     offset);
                    300: 
                    301: extern void            vm_page_init(
                    302:                                        vm_page_t       page,
                    303:                                        vm_offset_t     phys_addr);
                    304: 
                    305: extern void            vm_page_free(
                    306:                                        vm_page_t       page);
                    307: 
                    308: extern void            vm_page_activate(
                    309:                                        vm_page_t       page);
                    310: 
                    311: extern void            vm_page_deactivate(
                    312:                                        vm_page_t       page);
                    313: 
                    314: extern void            vm_page_rename(
                    315:                                        vm_page_t       page,
                    316:                                        vm_object_t     new_object,
                    317:                                        vm_offset_t     new_offset);
                    318: 
                    319: extern void            vm_page_insert(
                    320:                                        vm_page_t       page,
                    321:                                        vm_object_t     object,
                    322:                                        vm_offset_t     offset);
                    323: 
                    324: extern void            vm_page_replace(
                    325:                                        vm_page_t       mem,
                    326:                                        vm_object_t     object,
                    327:                                        vm_offset_t     offset);
                    328: 
                    329: extern void            vm_page_remove(
                    330:                                        vm_page_t       page);
                    331: 
                    332: extern void            vm_page_zero_fill(
                    333:                                        vm_page_t       page);
                    334: 
                    335: extern void            vm_page_part_zero_fill(
                    336:                                        vm_page_t       m,
                    337:                                        vm_offset_t     m_pa,
                    338:                                        vm_size_t       len);
                    339: 
                    340: extern void            vm_page_copy(
                    341:                                        vm_page_t       src_page,
                    342:                                        vm_page_t       dest_page);
                    343: 
                    344: extern void            vm_page_part_copy(
                    345:                                        vm_page_t       src_m,
                    346:                                        vm_offset_t     src_pa,
                    347:                                        vm_page_t       dst_m,
                    348:                                        vm_offset_t     dst_pa,
                    349:                                        vm_size_t       len);
                    350: 
                    351: extern void            vm_page_wire(
                    352:                                        vm_page_t       page);
                    353: 
                    354: extern void            vm_page_unwire(
                    355:                                        vm_page_t       page);
                    356: 
                    357: extern void            vm_set_page_size(void);
                    358: 
                    359: extern void            vm_page_gobble(
                    360:                                        vm_page_t      page);
                    361: 
                    362: extern kern_return_t   vm_page_prep(
                    363:                                        vm_page_t       m);
                    364: 
                    365: extern kern_return_t   vm_page_pin(
                    366:                                        vm_page_t       m);
                    367: 
                    368: extern kern_return_t   vm_page_unprep(
                    369:                                        vm_page_t       m);
                    370: 
                    371: extern kern_return_t   vm_page_unpin(
                    372:                                        vm_page_t       m);
                    373: 
                    374: extern void            cleanup_limbo_queue(void);
                    375: 
                    376: /*
                    377:  *     Functions implemented as macros. m->wanted and m->busy are
                    378:  *     protected by the object lock.
                    379:  */
                    380: 
                    381: #define PAGE_ASSERT_WAIT(m, interruptible)                     \
                    382:                MACRO_BEGIN                                     \
                    383:                (m)->wanted = TRUE;                             \
                    384:                assert_wait((event_t) (m), (interruptible));    \
                    385:                MACRO_END
                    386: 
                    387: #define PAGE_WAKEUP_DONE(m)                                    \
                    388:                MACRO_BEGIN                                     \
                    389:                (m)->busy = FALSE;                              \
                    390:                if ((m)->wanted) {                              \
                    391:                        (m)->wanted = FALSE;                    \
                    392:                        thread_wakeup((event_t) (m));           \
                    393:                }                                               \
                    394:                MACRO_END
                    395: 
                    396: #define PAGE_WAKEUP(m)                                         \
                    397:                MACRO_BEGIN                                     \
                    398:                if ((m)->wanted) {                              \
                    399:                        (m)->wanted = FALSE;                    \
                    400:                        thread_wakeup((event_t) (m));           \
                    401:                }                                               \
                    402:                MACRO_END
                    403: 
                    404: #define VM_PAGE_FREE(p)                        \
                    405:                MACRO_BEGIN                     \
                    406:                vm_page_lock_queues();          \
                    407:                vm_page_free(p);                \
                    408:                vm_page_unlock_queues();        \
                    409:                MACRO_END
                    410: 
                    411: #define VM_PAGE_GRAB_FICTITIOUS(M)                                     \
                    412:                MACRO_BEGIN                                             \
                    413:                while ((M = vm_page_grab_fictitious()) == VM_PAGE_NULL) \
                    414:                        vm_page_more_fictitious();                      \
                    415:                MACRO_END
                    416: 
                    417: #define        VM_PAGE_WAIT()  vm_page_wait()
                    418: 
                    419: #define vm_page_lock_queues()  mutex_lock(&vm_page_queue_lock)
                    420: #define vm_page_unlock_queues()        mutex_unlock(&vm_page_queue_lock)
                    421: #define vm_page_pin_lock()     simple_lock(&vm_page_preppin_lock)
                    422: #define vm_page_pin_unlock()   simple_unlock(&vm_page_preppin_lock)
                    423: 
                    424: #define VM_PAGE_QUEUES_REMOVE(mem)                             \
                    425:        MACRO_BEGIN                                             \
                    426:        if (mem->active) {                                      \
                    427:                assert(!mem->inactive);                         \
                    428:                queue_remove(&vm_page_queue_active,             \
                    429:                        mem, vm_page_t, pageq);                 \
                    430:                mem->active = FALSE;                            \
                    431:                if (!mem->fictitious)                           \
                    432:                        vm_page_active_count--;                 \
                    433:        }                                                       \
                    434:                                                                \
                    435:        if (mem->inactive) {                                    \
                    436:                assert(!mem->active);                           \
                    437:                queue_remove(&vm_page_queue_inactive,           \
                    438:                        mem, vm_page_t, pageq);                 \
                    439:                mem->inactive = FALSE;                          \
                    440:                if (!mem->fictitious)                           \
                    441:                        vm_page_inactive_count--;               \
                    442:        }                                                       \
                    443:        MACRO_END
                    444: 
                    445: /*
                    446:  * Data structure for automatic physical memory reservation.  Declared
                    447:  * here, defined in vm_resident.c.
                    448:  *
                    449:  * The following data structure is used to specify contiguous ranges
                    450:  * of physical memory that should be allocated before virtual memory
                    451:  * initialization.  Each element is a pair of addresses--the address
                    452:  * of the size of the chunk that should be allocated, the second the
                    453:  * location at which to place the pointer to that section when it is
                    454:  * allocated.
                    455:  *
                    456:  * The actual mechanism for allocating the contiguous physical memory
                    457:  * is machine dependent, and occurs during the machine dependent VM
                    458:  * initialization.
                    459:  *
                    460:  * This is defined as a pointer rather than a dimensionless array
                    461:  * because the PGI (intel 860) compiler can't handle dimensionless
                    462:  * arrays. 
                    463:  */
                    464: 
                    465: extern struct pmem_reserve {
                    466:   unsigned long *pmem_size;            /* In  */
                    467:   vm_offset_t *pmem_addr;              /* Out  */
                    468: } *pmem_reserve_ctl;
                    469: 
                    470: extern int pmem_reserve_ctl_size;
                    471: 
                    472: #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.