[BACK]Return to uvm_amap_i.h CVS log [TXT][DIR] Up to [local] / sys / uvm

Annotation of sys/uvm/uvm_amap_i.h, Revision 1.1

1.1     ! nbrk        1: /*     $OpenBSD: uvm_amap_i.h,v 1.18 2007/06/18 21:51:15 pedro Exp $   */
        !             2: /*     $NetBSD: uvm_amap_i.h,v 1.15 2000/11/25 06:27:59 chs Exp $      */
        !             3:
        !             4: /*
        !             5:  *
        !             6:  * Copyright (c) 1997 Charles D. Cranor and Washington University.
        !             7:  * All rights reserved.
        !             8:  *
        !             9:  * Redistribution and use in source and binary forms, with or without
        !            10:  * modification, are permitted provided that the following conditions
        !            11:  * are met:
        !            12:  * 1. Redistributions of source code must retain the above copyright
        !            13:  *    notice, this list of conditions and the following disclaimer.
        !            14:  * 2. Redistributions in binary form must reproduce the above copyright
        !            15:  *    notice, this list of conditions and the following disclaimer in the
        !            16:  *    documentation and/or other materials provided with the distribution.
        !            17:  * 3. All advertising materials mentioning features or use of this software
        !            18:  *    must display the following acknowledgement:
        !            19:  *      This product includes software developed by Charles D. Cranor and
        !            20:  *      Washington University.
        !            21:  * 4. The name of the author may not be used to endorse or promote products
        !            22:  *    derived from this software without specific prior written permission.
        !            23:  *
        !            24:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
        !            25:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
        !            26:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
        !            27:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
        !            28:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        !            29:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
        !            30:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
        !            31:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
        !            32:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
        !            33:  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
        !            34:  *
        !            35:  * from: Id: uvm_amap_i.h,v 1.1.2.4 1998/01/05 18:12:57 chuck Exp
        !            36:  */
        !            37:
        !            38: #ifndef _UVM_UVM_AMAP_I_H_
        !            39: #define _UVM_UVM_AMAP_I_H_
        !            40:
        !            41: /*
        !            42:  * uvm_amap_i.h
        !            43:  */
        !            44:
        !            45: /*
        !            46:  * if inlines are enabled always pull in these functions, otherwise
        !            47:  * pull them in only once (when we are compiling uvm_amap.c).
        !            48:  */
        !            49:
        !            50: #if defined(UVM_AMAP_INLINE) || defined(UVM_AMAP_C)
        !            51:
        !            52: /*
        !            53:  * amap_lookup: look up a page in an amap
        !            54:  *
        !            55:  * => amap should be locked by caller.
        !            56:  */
        !            57: AMAP_INLINE struct vm_anon *
        !            58: amap_lookup(aref, offset)
        !            59:        struct vm_aref *aref;
        !            60:        vaddr_t offset;
        !            61: {
        !            62:        int slot;
        !            63:        struct vm_amap *amap = aref->ar_amap;
        !            64:        UVMHIST_FUNC("amap_lookup"); UVMHIST_CALLED(maphist);
        !            65:
        !            66:        AMAP_B2SLOT(slot, offset);
        !            67:        slot += aref->ar_pageoff;
        !            68:
        !            69:        if (slot >= amap->am_nslot)
        !            70:                panic("amap_lookup: offset out of range");
        !            71:
        !            72:        UVMHIST_LOG(maphist, "<- done (amap=%p, offset=0x%lx, result=%p)",
        !            73:            amap, offset, amap->am_anon[slot], 0);
        !            74:        return(amap->am_anon[slot]);
        !            75: }
        !            76:
        !            77: /*
        !            78:  * amap_lookups: look up a range of pages in an amap
        !            79:  *
        !            80:  * => amap should be locked by caller.
        !            81:  * => XXXCDC: this interface is biased toward array-based amaps.  fix.
        !            82:  */
        !            83: AMAP_INLINE void
        !            84: amap_lookups(aref, offset, anons, npages)
        !            85:        struct vm_aref *aref;
        !            86:        vaddr_t offset;
        !            87:        struct vm_anon **anons;
        !            88:        int npages;
        !            89: {
        !            90:        int slot;
        !            91:        struct vm_amap *amap = aref->ar_amap;
        !            92:        UVMHIST_FUNC("amap_lookups"); UVMHIST_CALLED(maphist);
        !            93:
        !            94:        AMAP_B2SLOT(slot, offset);
        !            95:        slot += aref->ar_pageoff;
        !            96:
        !            97:        UVMHIST_LOG(maphist, "  slot=%ld, npages=%ld, nslot=%ld", slot, npages,
        !            98:                amap->am_nslot, 0);
        !            99:
        !           100:        if ((slot + (npages - 1)) >= amap->am_nslot)
        !           101:                panic("amap_lookups: offset out of range");
        !           102:
        !           103:        memcpy(anons, &amap->am_anon[slot], npages * sizeof(struct vm_anon *));
        !           104:
        !           105:        UVMHIST_LOG(maphist, "<- done", 0, 0, 0, 0);
        !           106:        return;
        !           107: }
        !           108:
        !           109: /*
        !           110:  * amap_add: add (or replace) a page to an amap
        !           111:  *
        !           112:  * => caller must lock amap.
        !           113:  * => if (replace) caller must lock anon because we might have to call
        !           114:  *     pmap_page_protect on the anon's page.
        !           115:  * => returns an "offset" which is meaningful to amap_unadd().
        !           116:  */
        !           117: AMAP_INLINE void
        !           118: amap_add(aref, offset, anon, replace)
        !           119:        struct vm_aref *aref;
        !           120:        vaddr_t offset;
        !           121:        struct vm_anon *anon;
        !           122:        boolean_t replace;
        !           123: {
        !           124:        int slot;
        !           125:        struct vm_amap *amap = aref->ar_amap;
        !           126:        UVMHIST_FUNC("amap_add"); UVMHIST_CALLED(maphist);
        !           127:
        !           128:        AMAP_B2SLOT(slot, offset);
        !           129:        slot += aref->ar_pageoff;
        !           130:
        !           131:        if (slot >= amap->am_nslot)
        !           132:                panic("amap_add: offset out of range");
        !           133:
        !           134:        if (replace) {
        !           135:
        !           136:                if (amap->am_anon[slot] == NULL)
        !           137:                        panic("amap_add: replacing null anon");
        !           138:                if (amap->am_anon[slot]->an_page != NULL &&
        !           139:                    (amap->am_flags & AMAP_SHARED) != 0) {
        !           140:                        pmap_page_protect(amap->am_anon[slot]->an_page,
        !           141:                            VM_PROT_NONE);
        !           142:                        /*
        !           143:                         * XXX: suppose page is supposed to be wired somewhere?
        !           144:                         */
        !           145:                }
        !           146:        } else {   /* !replace */
        !           147:                if (amap->am_anon[slot] != NULL)
        !           148:                        panic("amap_add: slot in use");
        !           149:
        !           150:                amap->am_bckptr[slot] = amap->am_nused;
        !           151:                amap->am_slots[amap->am_nused] = slot;
        !           152:                amap->am_nused++;
        !           153:        }
        !           154:        amap->am_anon[slot] = anon;
        !           155:        UVMHIST_LOG(maphist,
        !           156:            "<- done (amap=%p, offset=0x%lx, anon=%p, rep=%ld)",
        !           157:            amap, offset, anon, replace);
        !           158: }
        !           159:
        !           160: /*
        !           161:  * amap_unadd: remove a page from an amap
        !           162:  *
        !           163:  * => caller must lock amap
        !           164:  */
        !           165: AMAP_INLINE void
        !           166: amap_unadd(aref, offset)
        !           167:        struct vm_aref *aref;
        !           168:        vaddr_t offset;
        !           169: {
        !           170:        int ptr, slot;
        !           171:        struct vm_amap *amap = aref->ar_amap;
        !           172:        UVMHIST_FUNC("amap_unadd"); UVMHIST_CALLED(maphist);
        !           173:
        !           174:        AMAP_B2SLOT(slot, offset);
        !           175:        slot += aref->ar_pageoff;
        !           176:
        !           177:        if (slot >= amap->am_nslot)
        !           178:                panic("amap_unadd: offset out of range");
        !           179:
        !           180:        if (amap->am_anon[slot] == NULL)
        !           181:                panic("amap_unadd: nothing there");
        !           182:
        !           183:        amap->am_anon[slot] = NULL;
        !           184:        ptr = amap->am_bckptr[slot];
        !           185:
        !           186:        if (ptr != (amap->am_nused - 1)) {      /* swap to keep slots contig? */
        !           187:                amap->am_slots[ptr] = amap->am_slots[amap->am_nused - 1];
        !           188:                amap->am_bckptr[amap->am_slots[ptr]] = ptr;     /* back link */
        !           189:        }
        !           190:        amap->am_nused--;
        !           191:        UVMHIST_LOG(maphist, "<- done (amap=%p, slot=%ld)", amap, slot,0, 0);
        !           192: }
        !           193:
        !           194: /*
        !           195:  * amap_ref: gain a reference to an amap
        !           196:  *
        !           197:  * => amap must not be locked (we will lock)
        !           198:  * => "offset" and "len" are in units of pages
        !           199:  * => called at fork time to gain the child's reference
        !           200:  */
        !           201: AMAP_INLINE void
        !           202: amap_ref(amap, offset, len, flags)
        !           203:        struct vm_amap *amap;
        !           204:        vaddr_t offset;
        !           205:        vsize_t len;
        !           206:        int flags;
        !           207: {
        !           208:        UVMHIST_FUNC("amap_ref"); UVMHIST_CALLED(maphist);
        !           209:
        !           210:        amap->am_ref++;
        !           211:        if (flags & AMAP_SHARED)
        !           212:                amap->am_flags |= AMAP_SHARED;
        !           213: #ifdef UVM_AMAP_PPREF
        !           214:        if (amap->am_ppref == NULL && (flags & AMAP_REFALL) == 0 &&
        !           215:            len != amap->am_nslot)
        !           216:                amap_pp_establish(amap);
        !           217:        if (amap->am_ppref && amap->am_ppref != PPREF_NONE) {
        !           218:                if (flags & AMAP_REFALL)
        !           219:                        amap_pp_adjref(amap, 0, amap->am_nslot, 1);
        !           220:                else
        !           221:                        amap_pp_adjref(amap, offset, len, 1);
        !           222:        }
        !           223: #endif
        !           224:        UVMHIST_LOG(maphist,"<- done!  amap=%p", amap, 0, 0, 0);
        !           225: }
        !           226:
        !           227: /*
        !           228:  * amap_unref: remove a reference to an amap
        !           229:  *
        !           230:  * => caller must remove all pmap-level references to this amap before
        !           231:  *     dropping the reference
        !           232:  * => called from uvm_unmap_detach [only]  ... note that entry is no
        !           233:  *     longer part of a map and thus has no need for locking
        !           234:  * => amap must be unlocked (we will lock it).
        !           235:  */
        !           236: AMAP_INLINE void
        !           237: amap_unref(amap, offset, len, all)
        !           238:        struct vm_amap *amap;
        !           239:        vaddr_t offset;
        !           240:        vsize_t len;
        !           241:        boolean_t all;
        !           242: {
        !           243:        UVMHIST_FUNC("amap_unref"); UVMHIST_CALLED(maphist);
        !           244:
        !           245:        UVMHIST_LOG(maphist,"  amap=%p  refs=%ld, nused=%ld",
        !           246:            amap, amap->am_ref, amap->am_nused, 0);
        !           247:
        !           248:        /*
        !           249:         * if we are the last reference, free the amap and return.
        !           250:         */
        !           251:
        !           252:        if (amap->am_ref-- == 1) {
        !           253:                amap_wipeout(amap);     /* drops final ref and frees */
        !           254:                UVMHIST_LOG(maphist,"<- done (was last ref)!", 0, 0, 0, 0);
        !           255:                return;                 /* no need to unlock */
        !           256:        }
        !           257:
        !           258:        /*
        !           259:         * otherwise just drop the reference count(s)
        !           260:         */
        !           261:        if (amap->am_ref == 1 && (amap->am_flags & AMAP_SHARED) != 0)
        !           262:                amap->am_flags &= ~AMAP_SHARED; /* clear shared flag */
        !           263: #ifdef UVM_AMAP_PPREF
        !           264:        if (amap->am_ppref == NULL && all == 0 && len != amap->am_nslot)
        !           265:                amap_pp_establish(amap);
        !           266:        if (amap->am_ppref && amap->am_ppref != PPREF_NONE) {
        !           267:                if (all)
        !           268:                        amap_pp_adjref(amap, 0, amap->am_nslot, -1);
        !           269:                else
        !           270:                        amap_pp_adjref(amap, offset, len, -1);
        !           271:        }
        !           272: #endif
        !           273:
        !           274:        UVMHIST_LOG(maphist,"<- done!", 0, 0, 0, 0);
        !           275: }
        !           276:
        !           277: #endif /* defined(UVM_AMAP_INLINE) || defined(UVM_AMAP_C) */
        !           278:
        !           279: #endif /* _UVM_UVM_AMAP_I_H_ */

CVSweb