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