Annotation of sys/uvm/uvm_fault_i.h, Revision 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