Annotation of XNU/osfmk/vm/vm_page.h, revision 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.