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_amap_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_amap_i.h,v 1.20 2002/12/20 18:21:13 atatat 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_amap_i.h,v 1.1.2.4 1998/01/05 18:12:57 chuck Exp
   35  */
   36 
   37 /*
   38  * uvm_amap_i.h
   39  */
   40 
   41 /*
   42  * if inlines are enabled always pull in these functions, otherwise
   43  * pull them in only once (when we are compiling uvm_amap.c).
   44  */
   45 #if defined(UVM_AMAP_INLINE) || defined(UVM_AMAP_C)
   46 #ifndef _UVM_UVM_AMAP_I_H_
   47 #define _UVM_UVM_AMAP_I_H_
   48 
   49 /*
   50  * amap_lookup: look up a page in an amap
   51  *
   52  * => amap should be locked by caller.
   53  */
   54 AMAP_INLINE struct vm_anon *
   55 amap_lookup(aref, offset)
   56         struct vm_aref *aref;
   57         vaddr_t offset;
   58 {
   59         int slot;
   60         struct vm_amap *amap = aref->ar_amap;
   61         UVMHIST_FUNC("amap_lookup"); UVMHIST_CALLED(maphist);
   62 
   63         AMAP_B2SLOT(slot, offset);
   64         slot += aref->ar_pageoff;
   65 
   66         if (slot >= amap->am_nslot)
   67                 panic("amap_lookup: offset out of range");
   68 
   69         UVMHIST_LOG(maphist, "<- done (amap=0x%x, offset=0x%x, result=0x%x)",
   70             amap, offset, amap->am_anon[slot], 0);
   71         return(amap->am_anon[slot]);
   72 }
   73 
   74 /*
   75  * amap_lookups: look up a range of pages in an amap
   76  *
   77  * => amap should be locked by caller.
   78  * => XXXCDC: this interface is biased toward array-based amaps.  fix.
   79  */
   80 AMAP_INLINE void
   81 amap_lookups(aref, offset, anons, npages)
   82         struct vm_aref *aref;
   83         vaddr_t offset;
   84         struct vm_anon **anons;
   85         int npages;
   86 {
   87         int slot;
   88         struct vm_amap *amap = aref->ar_amap;
   89         UVMHIST_FUNC("amap_lookups"); UVMHIST_CALLED(maphist);
   90 
   91         AMAP_B2SLOT(slot, offset);
   92         slot += aref->ar_pageoff;
   93 
   94         UVMHIST_LOG(maphist, "  slot=%d, npages=%d, nslot=%d", slot, npages,
   95                 amap->am_nslot, 0);
   96 
   97         if ((slot + (npages - 1)) >= amap->am_nslot)
   98                 panic("amap_lookups: offset out of range");
   99 
  100         memcpy(anons, &amap->am_anon[slot], npages * sizeof(struct vm_anon *));
  101 
  102         UVMHIST_LOG(maphist, "<- done", 0, 0, 0, 0);
  103         return;
  104 }
  105 
  106 /*
  107  * amap_add: add (or replace) a page to an amap
  108  *
  109  * => caller must lock amap.
  110  * => if (replace) caller must lock anon because we might have to call
  111  *      pmap_page_protect on the anon's page.
  112  */
  113 AMAP_INLINE void
  114 amap_add(aref, offset, anon, replace)
  115         struct vm_aref *aref;
  116         vaddr_t offset;
  117         struct vm_anon *anon;
  118         boolean_t replace;
  119 {
  120         int slot;
  121         struct vm_amap *amap = aref->ar_amap;
  122         UVMHIST_FUNC("amap_add"); UVMHIST_CALLED(maphist);
  123 
  124         AMAP_B2SLOT(slot, offset);
  125         slot += aref->ar_pageoff;
  126 
  127         if (slot >= amap->am_nslot)
  128                 panic("amap_add: offset out of range");
  129 
  130         if (replace) {
  131 
  132                 if (amap->am_anon[slot] == NULL)
  133                         panic("amap_add: replacing null anon");
  134                 if (amap->am_anon[slot]->u.an_page != NULL &&
  135                     (amap->am_flags & AMAP_SHARED) != 0) {
  136                         pmap_page_protect(amap->am_anon[slot]->u.an_page,
  137                             VM_PROT_NONE);
  138                         /*
  139                          * XXX: suppose page is supposed to be wired somewhere?
  140                          */
  141                 }
  142         } else {   /* !replace */
  143                 if (amap->am_anon[slot] != NULL)
  144                         panic("amap_add: slot in use");
  145 
  146                 amap->am_bckptr[slot] = amap->am_nused;
  147                 amap->am_slots[amap->am_nused] = slot;
  148                 amap->am_nused++;
  149         }
  150         amap->am_anon[slot] = anon;
  151         UVMHIST_LOG(maphist,
  152             "<- done (amap=0x%x, offset=0x%x, anon=0x%x, rep=%d)",
  153             amap, offset, anon, replace);
  154 }
  155 
  156 /*
  157  * amap_unadd: remove a page from an amap
  158  *
  159  * => caller must lock amap
  160  */
  161 AMAP_INLINE void
  162 amap_unadd(aref, offset)
  163         struct vm_aref *aref;
  164         vaddr_t offset;
  165 {
  166         int ptr, slot;
  167         struct vm_amap *amap = aref->ar_amap;
  168         UVMHIST_FUNC("amap_unadd"); UVMHIST_CALLED(maphist);
  169 
  170         AMAP_B2SLOT(slot, offset);
  171         slot += aref->ar_pageoff;
  172 
  173         if (slot >= amap->am_nslot)
  174                 panic("amap_unadd: offset out of range");
  175 
  176         if (amap->am_anon[slot] == NULL)
  177                 panic("amap_unadd: nothing there");
  178 
  179         amap->am_anon[slot] = NULL;
  180         ptr = amap->am_bckptr[slot];
  181 
  182         if (ptr != (amap->am_nused - 1)) {      /* swap to keep slots contig? */
  183                 amap->am_slots[ptr] = amap->am_slots[amap->am_nused - 1];
  184                 amap->am_bckptr[amap->am_slots[ptr]] = ptr;     /* back link */
  185         }
  186         amap->am_nused--;
  187         UVMHIST_LOG(maphist, "<- done (amap=0x%x, slot=0x%x)", amap, slot,0, 0);
  188 }
  189 
  190 /*
  191  * amap_ref: gain a reference to an amap
  192  *
  193  * => amap must not be locked (we will lock)
  194  * => "offset" and "len" are in units of pages
  195  * => called at fork time to gain the child's reference
  196  */
  197 AMAP_INLINE void
  198 amap_ref(amap, offset, len, flags)
  199         struct vm_amap *amap;
  200         vaddr_t offset;
  201         vsize_t len;
  202         int flags;
  203 {
  204         UVMHIST_FUNC("amap_ref"); UVMHIST_CALLED(maphist);
  205 
  206         amap_lock(amap);
  207         if (flags & AMAP_SHARED)
  208                 amap->am_flags |= AMAP_SHARED;
  209 #ifdef UVM_AMAP_PPREF
  210         if (amap->am_ppref == NULL && (flags & AMAP_REFALL) == 0 &&
  211             len != amap->am_nslot)
  212                 amap_pp_establish(amap, offset);
  213 #endif
  214         amap->am_ref++;
  215 #ifdef UVM_AMAP_PPREF
  216         if (amap->am_ppref && amap->am_ppref != PPREF_NONE) {
  217                 if (flags & AMAP_REFALL)
  218                         amap_pp_adjref(amap, 0, amap->am_nslot, 1);
  219                 else
  220                         amap_pp_adjref(amap, offset, len, 1);
  221         }
  222 #endif
  223         amap_unlock(amap);
  224         UVMHIST_LOG(maphist,"<- done!  amap=0x%x", amap, 0, 0, 0);
  225 }
  226 
  227 /*
  228  * amap_unref: remove a reference to an amap
  229  *
  230  * => caller must remove all pmap-level references to this amap before
  231  *      dropping the reference
  232  * => called from uvm_unmap_detach [only]  ... note that entry is no
  233  *      longer part of a map and thus has no need for locking
  234  * => amap must be unlocked (we will lock it).
  235  */
  236 AMAP_INLINE void
  237 amap_unref(amap, offset, len, all)
  238         struct vm_amap *amap;
  239         vaddr_t offset;
  240         vsize_t len;
  241         boolean_t all;
  242 {
  243         UVMHIST_FUNC("amap_unref"); UVMHIST_CALLED(maphist);
  244 
  245         /*
  246          * lock it
  247          */
  248         amap_lock(amap);
  249         UVMHIST_LOG(maphist,"  amap=0x%x  refs=%d, nused=%d",
  250             amap, amap->am_ref, amap->am_nused, 0);
  251 
  252         /*
  253          * if we are the last reference, free the amap and return.
  254          */
  255 
  256         if (amap->am_ref == 1) {
  257                 amap_wipeout(amap);     /* drops final ref and frees */
  258                 UVMHIST_LOG(maphist,"<- done (was last ref)!", 0, 0, 0, 0);
  259                 return;                 /* no need to unlock */
  260         }
  261 
  262         /*
  263          * otherwise just drop the reference count(s)
  264          */
  265 
  266         amap->am_ref--;
  267         if (amap->am_ref == 1 && (amap->am_flags & AMAP_SHARED) != 0)
  268                 amap->am_flags &= ~AMAP_SHARED; /* clear shared flag */
  269 #ifdef UVM_AMAP_PPREF
  270         if (amap->am_ppref == NULL && all == 0 && len != amap->am_nslot)
  271                 amap_pp_establish(amap, offset);
  272         if (amap->am_ppref && amap->am_ppref != PPREF_NONE) {
  273                 if (all)
  274                         amap_pp_adjref(amap, 0, amap->am_nslot, -1);
  275                 else
  276                         amap_pp_adjref(amap, offset, len, -1);
  277         }
  278 #endif
  279         amap_unlock(amap);
  280 
  281         UVMHIST_LOG(maphist,"<- done!", 0, 0, 0, 0);
  282 }
  283 
  284 #endif /* _UVM_UVM_AMAP_I_H_ */
  285 
  286 #endif /* defined(UVM_AMAP_INLINE) || defined(UVM_AMAP_C) */
  287 

Cache object: 133dd53c158fd3cc682965a890cebdf3


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