The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/uvm/uvm_fault_i.h

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*      $NetBSD: uvm_fault_i.h,v 1.21 2006/02/16 20:17:20 perry Exp $   */
    2 
    3 /*
    4  *
    5  * Copyright (c) 1997 Charles D. Cranor and Washington University.
    6  * All rights reserved.
    7  *
    8  * Redistribution and use in source and binary forms, with or without
    9  * modification, are permitted provided that the following conditions
   10  * are met:
   11  * 1. Redistributions of source code must retain the above copyright
   12  *    notice, this list of conditions and the following disclaimer.
   13  * 2. Redistributions in binary form must reproduce the above copyright
   14  *    notice, this list of conditions and the following disclaimer in the
   15  *    documentation and/or other materials provided with the distribution.
   16  * 3. All advertising materials mentioning features or use of this software
   17  *    must display the following acknowledgement:
   18  *      This product includes software developed by Charles D. Cranor and
   19  *      Washington University.
   20  * 4. The name of the author may not be used to endorse or promote products
   21  *    derived from this software without specific prior written permission.
   22  *
   23  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   24  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   25  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   26  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   27  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   28  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   29  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   30  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   31  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   32  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   33  *
   34  * from: Id: uvm_fault_i.h,v 1.1.6.1 1997/12/08 16:07:12 chuck Exp
   35  */
   36 
   37 #ifndef _UVM_UVM_FAULT_I_H_
   38 #define _UVM_UVM_FAULT_I_H_
   39 
   40 /*
   41  * uvm_fault_i.h: fault inline functions
   42  */
   43 
   44 /*
   45  * uvmfault_unlockmaps: unlock the maps
   46  */
   47 
   48 static __inline void
   49 uvmfault_unlockmaps(struct uvm_faultinfo *ufi, boolean_t write_locked)
   50 {
   51         /*
   52          * ufi can be NULL when this isn't really a fault,
   53          * but merely paging in anon data.
   54          */
   55 
   56         if (ufi == NULL) {
   57                 return;
   58         }
   59 
   60         if (write_locked) {
   61                 vm_map_unlock(ufi->map);
   62         } else {
   63                 vm_map_unlock_read(ufi->map);
   64         }
   65 }
   66 
   67 /*
   68  * uvmfault_unlockall: unlock everything passed in.
   69  *
   70  * => maps must be read-locked (not write-locked).
   71  */
   72 
   73 static __inline void
   74 uvmfault_unlockall(struct uvm_faultinfo *ufi, struct vm_amap *amap,
   75     struct uvm_object *uobj, struct vm_anon *anon)
   76 {
   77 
   78         if (anon)
   79                 simple_unlock(&anon->an_lock);
   80         if (uobj)
   81                 simple_unlock(&uobj->vmobjlock);
   82         if (amap)
   83                 amap_unlock(amap);
   84         uvmfault_unlockmaps(ufi, FALSE);
   85 }
   86 
   87 /*
   88  * uvmfault_lookup: lookup a virtual address in a map
   89  *
   90  * => caller must provide a uvm_faultinfo structure with the IN
   91  *      params properly filled in
   92  * => we will lookup the map entry (handling submaps) as we go
   93  * => if the lookup is a success we will return with the maps locked
   94  * => if "write_lock" is TRUE, we write_lock the map, otherwise we only
   95  *      get a read lock.
   96  * => note that submaps can only appear in the kernel and they are
   97  *      required to use the same virtual addresses as the map they
   98  *      are referenced by (thus address translation between the main
   99  *      map and the submap is unnecessary).
  100  */
  101 
  102 static __inline boolean_t
  103 uvmfault_lookup(struct uvm_faultinfo *ufi, boolean_t write_lock)
  104 {
  105         struct vm_map *tmpmap;
  106 
  107         /*
  108          * init ufi values for lookup.
  109          */
  110 
  111         ufi->map = ufi->orig_map;
  112         ufi->size = ufi->orig_size;
  113 
  114         /*
  115          * keep going down levels until we are done.   note that there can
  116          * only be two levels so we won't loop very long.
  117          */
  118 
  119         /*CONSTCOND*/
  120         while (1) {
  121                 /*
  122                  * Make sure this is not an "interrupt safe" map.
  123                  * Such maps are never supposed to be involved in
  124                  * a fault.
  125                  */
  126                 if (ufi->map->flags & VM_MAP_INTRSAFE)
  127                         return (FALSE);
  128 
  129                 /*
  130                  * lock map
  131                  */
  132                 if (write_lock) {
  133                         vm_map_lock(ufi->map);
  134                 } else {
  135                         vm_map_lock_read(ufi->map);
  136                 }
  137 
  138                 /*
  139                  * lookup
  140                  */
  141                 if (!uvm_map_lookup_entry(ufi->map, ufi->orig_rvaddr,
  142                                                                 &ufi->entry)) {
  143                         uvmfault_unlockmaps(ufi, write_lock);
  144                         return(FALSE);
  145                 }
  146 
  147                 /*
  148                  * reduce size if necessary
  149                  */
  150                 if (ufi->entry->end - ufi->orig_rvaddr < ufi->size)
  151                         ufi->size = ufi->entry->end - ufi->orig_rvaddr;
  152 
  153                 /*
  154                  * submap?    replace map with the submap and lookup again.
  155                  * note: VAs in submaps must match VAs in main map.
  156                  */
  157                 if (UVM_ET_ISSUBMAP(ufi->entry)) {
  158                         tmpmap = ufi->entry->object.sub_map;
  159                         if (write_lock) {
  160                                 vm_map_unlock(ufi->map);
  161                         } else {
  162                                 vm_map_unlock_read(ufi->map);
  163                         }
  164                         ufi->map = tmpmap;
  165                         continue;
  166                 }
  167 
  168                 /*
  169                  * got it!
  170                  */
  171 
  172                 ufi->mapv = ufi->map->timestamp;
  173                 return(TRUE);
  174 
  175         }       /* while loop */
  176 
  177         /*NOTREACHED*/
  178 }
  179 
  180 /*
  181  * uvmfault_relock: attempt to relock the same version of the map
  182  *
  183  * => fault data structures should be unlocked before calling.
  184  * => if a success (TRUE) maps will be locked after call.
  185  */
  186 
  187 static __inline boolean_t
  188 uvmfault_relock(struct uvm_faultinfo *ufi)
  189 {
  190         /*
  191          * ufi can be NULL when this isn't really a fault,
  192          * but merely paging in anon data.
  193          */
  194 
  195         if (ufi == NULL) {
  196                 return TRUE;
  197         }
  198 
  199         uvmexp.fltrelck++;
  200 
  201         /*
  202          * relock map.   fail if version mismatch (in which case nothing
  203          * gets locked).
  204          */
  205 
  206         vm_map_lock_read(ufi->map);
  207         if (ufi->mapv != ufi->map->timestamp) {
  208                 vm_map_unlock_read(ufi->map);
  209                 return(FALSE);
  210         }
  211 
  212         uvmexp.fltrelckok++;
  213         return(TRUE);
  214 }
  215 
  216 #endif /* _UVM_UVM_FAULT_I_H_ */

Cache object: efa8700c9fa057907006b2e93a77ab41


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.