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/vm/phys_pager.c

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 /*
    2  * Copyright (c) 2000 Peter Wemm
    3  *
    4  * Redistribution and use in source and binary forms, with or without
    5  * modification, are permitted provided that the following conditions
    6  * are met:
    7  * 1. Redistributions of source code must retain the above copyright
    8  *    notice, this list of conditions and the following disclaimer.
    9  * 2. Redistributions in binary form must reproduce the above copyright
   10  *    notice, this list of conditions and the following disclaimer in the
   11  *    documentation and/or other materials provided with the distribution.
   12  *
   13  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
   14  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   16  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
   17  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   18  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   19  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   20  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   21  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   22  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   23  * SUCH DAMAGE.
   24  *
   25  * $FreeBSD$
   26  */
   27 
   28 #include <sys/param.h>
   29 #include <sys/systm.h>
   30 #include <sys/linker_set.h>
   31 #include <sys/conf.h>
   32 #include <sys/mman.h>
   33 #include <sys/sysctl.h>
   34 
   35 #include <vm/vm.h>
   36 #include <vm/vm_object.h>
   37 #include <vm/vm_page.h>
   38 #include <vm/vm_pager.h>
   39 #include <vm/vm_zone.h>
   40 
   41 /* list of device pager objects */
   42 static struct pagerlst phys_pager_object_list;
   43 
   44 static int phys_pager_alloc_lock, phys_pager_alloc_lock_want;
   45 
   46 static void
   47 phys_pager_init(void)
   48 {
   49 
   50         TAILQ_INIT(&phys_pager_object_list);
   51 }
   52 
   53 static vm_object_t
   54 phys_pager_alloc(void *handle, vm_ooffset_t size, vm_prot_t prot,
   55                  vm_ooffset_t foff)
   56 {
   57         vm_object_t object;
   58 
   59         /*
   60          * Offset should be page aligned.
   61          */
   62         if (foff & PAGE_MASK)
   63                 return (NULL);
   64 
   65         size = round_page(size);
   66 
   67         if (handle != NULL) {
   68                 /*
   69                  * Lock to prevent object creation race condition.
   70                  */
   71                 while (phys_pager_alloc_lock) {
   72                         phys_pager_alloc_lock_want++;
   73                         tsleep(&phys_pager_alloc_lock, PVM, "ppall", 0);
   74                         phys_pager_alloc_lock_want--;
   75                 }
   76                 phys_pager_alloc_lock = 1;
   77         
   78                 /*
   79                  * Look up pager, creating as necessary.
   80                  */
   81                 object = vm_pager_object_lookup(&phys_pager_object_list, handle);
   82                 if (object == NULL) {
   83                         /*
   84                          * Allocate object and associate it with the pager.
   85                          */
   86                         object = vm_object_allocate(OBJT_PHYS,
   87                                 OFF_TO_IDX(foff + size));
   88                         object->handle = handle;
   89                         TAILQ_INSERT_TAIL(&phys_pager_object_list, object,
   90                             pager_object_list);
   91                 } else {
   92                         /*
   93                          * Gain a reference to the object.
   94                          */
   95                         vm_object_reference(object);
   96                         if (OFF_TO_IDX(foff + size) > object->size)
   97                                 object->size = OFF_TO_IDX(foff + size);
   98                 }
   99                 phys_pager_alloc_lock = 0;
  100                 if (phys_pager_alloc_lock_want)
  101                         wakeup(&phys_pager_alloc_lock);
  102         } else {
  103                 object = vm_object_allocate(OBJT_PHYS,
  104                         OFF_TO_IDX(foff + size));
  105         }
  106 
  107         return (object);
  108 }
  109 
  110 static void
  111 phys_pager_dealloc(vm_object_t object)
  112 {
  113 
  114         if (object->handle != NULL)
  115                 TAILQ_REMOVE(&phys_pager_object_list, object, pager_object_list);
  116 }
  117 
  118 static int
  119 phys_pager_getpages(vm_object_t object, vm_page_t *m, int count, int reqpage)
  120 {
  121         int i, s;
  122 
  123         s = splvm();
  124         /*
  125          * Fill as many pages as vm_fault has allocated for us.
  126          */
  127         for (i = 0; i < count; i++) {
  128                 if ((m[i]->flags & PG_ZERO) == 0)
  129                         vm_page_zero_fill(m[i]);
  130                 vm_page_flag_set(m[i], PG_ZERO);
  131                 /* Switch off pv_entries */
  132                 vm_page_unmanage(m[i]);
  133                 m[i]->valid = VM_PAGE_BITS_ALL;
  134                 m[i]->dirty = 0;
  135                 /* The requested page must remain busy, the others not. */
  136                 if (reqpage != i) {
  137                         vm_page_flag_clear(m[i], PG_BUSY);
  138                         m[i]->busy = 0;
  139                 }
  140         }
  141         splx(s);
  142 
  143         return (VM_PAGER_OK);
  144 }
  145 
  146 static void
  147 phys_pager_putpages(vm_object_t object, vm_page_t *m, int count, boolean_t sync,
  148                     int *rtvals)
  149 {
  150 
  151         panic("phys_pager_putpage called");
  152 }
  153 
  154 /*
  155  * Implement a pretty aggressive clustered getpages strategy.  Hint that
  156  * everything in an entire 4MB window should be prefaulted at once.
  157  *
  158  * XXX 4MB (1024 slots per page table page) is convenient for x86,
  159  * but may not be for other arches.
  160  */
  161 #ifndef PHYSCLUSTER
  162 #define PHYSCLUSTER 1024
  163 #endif
  164 static boolean_t
  165 phys_pager_haspage(vm_object_t object, vm_pindex_t pindex, int *before,
  166                    int *after)
  167 {
  168         vm_pindex_t base, end;
  169 
  170         base = pindex & (~(PHYSCLUSTER - 1));
  171         end = base + (PHYSCLUSTER - 1);
  172         if (before != NULL)
  173                 *before = pindex - base;
  174         if (after != NULL)
  175                 *after = end - pindex;
  176         return (TRUE);
  177 }
  178 
  179 struct pagerops physpagerops = {
  180         phys_pager_init,
  181         phys_pager_alloc,
  182         phys_pager_dealloc,
  183         phys_pager_getpages,
  184         phys_pager_putpages,
  185         phys_pager_haspage,
  186         NULL
  187 };

Cache object: bbc485d77a07cbc7eb92d8bc7b728919


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