root/uvm/uvm_fault_i.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. uvmfault_unlockmaps
  2. uvmfault_unlockall
  3. uvmfault_lookup
  4. uvmfault_relock

    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_ */

/* [<][>][^][v][top][bottom][index][help] */