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

Cache object: 2b62f28c7228f8ff0e87a30625ffb139


[ 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.