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_io.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 /*      $OpenBSD: uvm_io.c,v 1.30 2022/10/07 14:59:39 deraadt Exp $     */
    2 /*      $NetBSD: uvm_io.c,v 1.12 2000/06/27 17:29:23 mrg Exp $  */
    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  *
   17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   27  *
   28  * from: Id: uvm_io.c,v 1.1.2.2 1997/12/30 12:02:00 mrg Exp
   29  */
   30 
   31 /*
   32  * uvm_io.c: uvm i/o ops
   33  */
   34 
   35 #include <sys/param.h>
   36 #include <sys/systm.h>
   37 #include <sys/mman.h>
   38 #include <sys/uio.h>
   39 
   40 #include <uvm/uvm.h>
   41 
   42 /*
   43  * functions
   44  */
   45 
   46 /*
   47  * uvm_io: perform I/O on a map
   48  *
   49  * => caller must have a reference to "map" so that it doesn't go away
   50  *    while we are working.
   51  */
   52 
   53 int
   54 uvm_io(vm_map_t map, struct uio *uio, int flags)
   55 {
   56         vaddr_t baseva, endva, pageoffset, kva;
   57         vsize_t chunksz, togo, sz;
   58         struct uvm_map_deadq dead_entries;
   59         int error, extractflags;
   60 
   61         /*
   62          * step 0: sanity checks and set up for copy loop.  start with a
   63          * large chunk size.  if we have trouble finding vm space we will
   64          * reduce it.
   65          */
   66         if (uio->uio_resid == 0)
   67                 return(0);
   68         togo = uio->uio_resid;
   69 
   70         baseva = (vaddr_t) uio->uio_offset;
   71         endva = baseva + (togo - 1);
   72 
   73         if (endva < baseva)   /* wrap around? */
   74                 return(EIO);
   75 
   76         if (baseva >= VM_MAXUSER_ADDRESS)
   77                 return(0);
   78         if (endva >= VM_MAXUSER_ADDRESS)
   79                 /* EOF truncate */
   80                 togo = togo - (endva - VM_MAXUSER_ADDRESS + 1);
   81         pageoffset = baseva & PAGE_MASK;
   82         baseva = trunc_page(baseva);
   83         chunksz = min(round_page(togo + pageoffset), MAXBSIZE);
   84         error = 0;
   85 
   86         extractflags = 0;
   87         if (flags & UVM_IO_FIXPROT)
   88                 extractflags |= UVM_EXTRACT_FIXPROT;
   89 
   90         /*
   91          * step 1: main loop...  while we've got data to move
   92          */
   93         for (/*null*/; togo > 0 ; pageoffset = 0) {
   94 
   95                 /*
   96                  * step 2: extract mappings from the map into kernel_map
   97                  */
   98                 error = uvm_map_extract(map, baseva, chunksz, &kva,
   99                     extractflags);
  100                 if (error) {
  101 
  102                         /* retry with a smaller chunk... */
  103                         if (error == ENOMEM && chunksz > PAGE_SIZE) {
  104                                 chunksz = trunc_page(chunksz / 2);
  105                                 if (chunksz < PAGE_SIZE)
  106                                         chunksz = PAGE_SIZE;
  107                                 continue;
  108                         }
  109 
  110                         break;
  111                 }
  112 
  113                 /*
  114                  * step 3: move a chunk of data
  115                  */
  116                 sz = chunksz - pageoffset;
  117                 if (sz > togo)
  118                         sz = togo;
  119                 error = uiomove((caddr_t) (kva + pageoffset), sz, uio);
  120                 togo -= sz;
  121                 baseva += chunksz;
  122 
  123 
  124                 /*
  125                  * step 4: unmap the area of kernel memory
  126                  */
  127                 vm_map_lock(kernel_map);
  128                 TAILQ_INIT(&dead_entries);
  129                 uvm_unmap_remove(kernel_map, kva, kva+chunksz,
  130                     &dead_entries, FALSE, TRUE, FALSE);
  131                 vm_map_unlock(kernel_map);
  132                 uvm_unmap_detach(&dead_entries, AMAP_REFALL);
  133 
  134                 if (error)
  135                         break;
  136         }
  137 
  138         return (error);
  139 }

Cache object: 5ad7899793b1f48b35624609abd02dd5


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