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

Annotation of sys/uvm/uvm_fault_i.h, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: uvm_fault_i.h,v 1.12 2007/05/31 21:20:30 thib Exp $   */
                      2: /*     $NetBSD: uvm_fault_i.h,v 1.11 2000/06/26 14:21:17 mrg 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_fault_i.h,v 1.1.6.1 1997/12/08 16:07:12 chuck Exp
                     36:  */
                     37:
                     38: #ifndef _UVM_UVM_FAULT_I_H_
                     39: #define _UVM_UVM_FAULT_I_H_
                     40:
                     41: /*
                     42:  * uvm_fault_i.h: fault inline functions
                     43:  */
                     44: static boolean_t uvmfault_lookup(struct uvm_faultinfo *, boolean_t);
                     45: static boolean_t uvmfault_relock(struct uvm_faultinfo *);
                     46: static void uvmfault_unlockall(struct uvm_faultinfo *, struct vm_amap *,
                     47:                                    struct uvm_object *, struct vm_anon *);
                     48: static void uvmfault_unlockmaps(struct uvm_faultinfo *, boolean_t);
                     49:
                     50: /*
                     51:  * uvmfault_unlockmaps: unlock the maps
                     52:  */
                     53:
                     54: static __inline void
                     55: uvmfault_unlockmaps(ufi, write_locked)
                     56:        struct uvm_faultinfo *ufi;
                     57:        boolean_t write_locked;
                     58: {
                     59:        /*
                     60:         * ufi can be NULL when this isn't really a fault,
                     61:         * but merely paging in anon data.
                     62:         */
                     63:
                     64:        if (ufi == NULL) {
                     65:                return;
                     66:        }
                     67:
                     68:        if (write_locked) {
                     69:                vm_map_unlock(ufi->map);
                     70:        } else {
                     71:                vm_map_unlock_read(ufi->map);
                     72:        }
                     73: }
                     74:
                     75: /*
                     76:  * uvmfault_unlockall: unlock everything passed in.
                     77:  *
                     78:  * => maps must be read-locked (not write-locked).
                     79:  */
                     80:
                     81: static __inline void
                     82: uvmfault_unlockall(ufi, amap, uobj, anon)
                     83:        struct uvm_faultinfo *ufi;
                     84:        struct vm_amap *amap;
                     85:        struct uvm_object *uobj;
                     86:        struct vm_anon *anon;
                     87: {
                     88:
                     89:        if (anon)
                     90:                simple_unlock(&anon->an_lock);
                     91:        if (uobj)
                     92:                simple_unlock(&uobj->vmobjlock);
                     93:        uvmfault_unlockmaps(ufi, FALSE);
                     94: }
                     95:
                     96: /*
                     97:  * uvmfault_lookup: lookup a virtual address in a map
                     98:  *
                     99:  * => caller must provide a uvm_faultinfo structure with the IN
                    100:  *     params properly filled in
                    101:  * => we will lookup the map entry (handling submaps) as we go
                    102:  * => if the lookup is a success we will return with the maps locked
                    103:  * => if "write_lock" is TRUE, we write_lock the map, otherwise we only
                    104:  *     get a read lock.
                    105:  * => note that submaps can only appear in the kernel and they are
                    106:  *     required to use the same virtual addresses as the map they
                    107:  *     are referenced by (thus address translation between the main
                    108:  *     map and the submap is unnecessary).
                    109:  */
                    110:
                    111: static __inline boolean_t
                    112: uvmfault_lookup(ufi, write_lock)
                    113:        struct uvm_faultinfo *ufi;
                    114:        boolean_t write_lock;
                    115: {
                    116:        vm_map_t tmpmap;
                    117:
                    118:        /*
                    119:         * init ufi values for lookup.
                    120:         */
                    121:
                    122:        ufi->map = ufi->orig_map;
                    123:        ufi->size = ufi->orig_size;
                    124:
                    125:        /*
                    126:         * keep going down levels until we are done.   note that there can
                    127:         * only be two levels so we won't loop very long.
                    128:         */
                    129:
                    130:        while (1) {
                    131:
                    132:                /*
                    133:                 * lock map
                    134:                 */
                    135:                if (write_lock) {
                    136:                        vm_map_lock(ufi->map);
                    137:                } else {
                    138:                        vm_map_lock_read(ufi->map);
                    139:                }
                    140:
                    141:                /*
                    142:                 * lookup
                    143:                 */
                    144:                if (!uvm_map_lookup_entry(ufi->map, ufi->orig_rvaddr,
                    145:                                                                &ufi->entry)) {
                    146:                        uvmfault_unlockmaps(ufi, write_lock);
                    147:                        return(FALSE);
                    148:                }
                    149:
                    150:                /*
                    151:                 * reduce size if necessary
                    152:                 */
                    153:                if (ufi->entry->end - ufi->orig_rvaddr < ufi->size)
                    154:                        ufi->size = ufi->entry->end - ufi->orig_rvaddr;
                    155:
                    156:                /*
                    157:                 * submap?    replace map with the submap and lookup again.
                    158:                 * note: VAs in submaps must match VAs in main map.
                    159:                 */
                    160:                if (UVM_ET_ISSUBMAP(ufi->entry)) {
                    161:                        tmpmap = ufi->entry->object.sub_map;
                    162:                        if (write_lock) {
                    163:                                vm_map_unlock(ufi->map);
                    164:                        } else {
                    165:                                vm_map_unlock_read(ufi->map);
                    166:                        }
                    167:                        ufi->map = tmpmap;
                    168:                        continue;
                    169:                }
                    170:
                    171:                /*
                    172:                 * got it!
                    173:                 */
                    174:
                    175:                ufi->mapv = ufi->map->timestamp;
                    176:                return(TRUE);
                    177:
                    178:        }       /* while loop */
                    179:
                    180:        /*NOTREACHED*/
                    181: }
                    182:
                    183: /*
                    184:  * uvmfault_relock: attempt to relock the same version of the map
                    185:  *
                    186:  * => fault data structures should be unlocked before calling.
                    187:  * => if a success (TRUE) maps will be locked after call.
                    188:  */
                    189:
                    190: static __inline boolean_t
                    191: uvmfault_relock(ufi)
                    192:        struct uvm_faultinfo *ufi;
                    193: {
                    194:        /*
                    195:         * ufi can be NULL when this isn't really a fault,
                    196:         * but merely paging in anon data.
                    197:         */
                    198:
                    199:        if (ufi == NULL) {
                    200:                return TRUE;
                    201:        }
                    202:
                    203:        uvmexp.fltrelck++;
                    204:
                    205:        /*
                    206:         * relock map.   fail if version mismatch (in which case nothing
                    207:         * gets locked).
                    208:         */
                    209:
                    210:        vm_map_lock_read(ufi->map);
                    211:        if (ufi->mapv != ufi->map->timestamp) {
                    212:                vm_map_unlock_read(ufi->map);
                    213:                return(FALSE);
                    214:        }
                    215:
                    216:        uvmexp.fltrelckok++;
                    217:        return(TRUE);           /* got it! */
                    218: }
                    219:
                    220: #endif /* _UVM_UVM_FAULT_I_H_ */

CVSweb