[BACK]Return to uvm_io.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / uvm

Annotation of src/sys/uvm/uvm_io.c, Revision 1.10

1.10    ! pk          1: /*     $NetBSD: uvm_io.c,v 1.9 2000/06/02 11:47:53 pk Exp $    */
1.1       mrg         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.
1.3       mrg        33:  *
                     34:  * from: Id: uvm_io.c,v 1.1.2.2 1997/12/30 12:02:00 mrg Exp
1.1       mrg        35:  */
                     36:
                     37: /*
                     38:  * uvm_io.c: uvm i/o ops
                     39:  */
                     40:
                     41: #include <sys/param.h>
                     42: #include <sys/systm.h>
                     43: #include <sys/mman.h>
                     44: #include <sys/proc.h>
                     45: #include <sys/malloc.h>
                     46: #include <sys/uio.h>
                     47:
                     48: #include <vm/vm.h>
                     49: #include <vm/vm_page.h>
                     50: #include <vm/vm_kern.h>
                     51:
                     52: #include <uvm/uvm.h>
                     53:
                     54: /*
                     55:  * functions
                     56:  */
                     57:
                     58: /*
                     59:  * uvm_io: perform I/O on a map
                     60:  *
                     61:  * => caller must have a reference to "map" so that it doesn't go away
                     62:  *    while we are working.
                     63:  */
                     64:
1.4       mrg        65: int
                     66: uvm_io(map, uio)
                     67:        vm_map_t map;
                     68:        struct uio *uio;
1.1       mrg        69: {
1.6       eeh        70:        vaddr_t baseva, endva, pageoffset, kva;
                     71:        vsize_t chunksz, togo, sz;
1.4       mrg        72:        vm_map_entry_t dead_entries;
                     73:        int error;
                     74:
                     75:        /*
                     76:         * step 0: sanity checks and set up for copy loop.  start with a
                     77:         * large chunk size.  if we have trouble finding vm space we will
                     78:         * reduce it.
                     79:         */
                     80:
                     81:        if (uio->uio_resid == 0)
                     82:                return(0);
                     83:        togo = uio->uio_resid;
                     84:
1.6       eeh        85:        baseva = (vaddr_t) uio->uio_offset;
1.4       mrg        86:        endva = baseva + (togo - 1);
                     87:
                     88:        if (endva < baseva)   /* wrap around? */
                     89:                return(EIO);
                     90:
                     91:        if (baseva >= VM_MAXUSER_ADDRESS)
                     92:                return(0);
                     93:        if (endva >= VM_MAXUSER_ADDRESS)
                     94:                /* EOF truncate */
                     95:                togo = togo - (endva - VM_MAXUSER_ADDRESS + 1);
                     96:        pageoffset = baseva & PAGE_MASK;
                     97:        baseva = trunc_page(baseva);
                     98:        chunksz = min(round_page(togo + pageoffset), MAXBSIZE);
                     99:        error = 0;
                    100:
                    101:        /*
                    102:         * step 1: main loop...  while we've got data to move
                    103:         */
                    104:
                    105:        for (/*null*/; togo > 0 ; pageoffset = 0) {
                    106:
                    107:                /*
                    108:                 * step 2: extract mappings from the map into kernel_map
                    109:                 */
1.1       mrg       110:
1.4       mrg       111:                error = uvm_map_extract(map, baseva, chunksz, kernel_map, &kva,
1.1       mrg       112:                            UVM_EXTRACT_QREF | UVM_EXTRACT_CONTIG |
                    113:                            UVM_EXTRACT_FIXPROT);
1.4       mrg       114:                if (error) {
1.1       mrg       115:
1.4       mrg       116:                        /* retry with a smaller chunk... */
                    117:                        if (error == ENOMEM && chunksz > PAGE_SIZE) {
                    118:                                chunksz = trunc_page(chunksz / 2);
                    119:                                if (chunksz < PAGE_SIZE)
                    120:                                        chunksz = PAGE_SIZE;
                    121:                                continue;
                    122:                        }
                    123:
                    124:                        break;
                    125:                }
                    126:
                    127:                /*
                    128:                 * step 3: move a chunk of data
                    129:                 */
                    130:
                    131:                sz = chunksz - pageoffset;
                    132:                if (sz > togo)
                    133:                        sz = togo;
                    134:                error = uiomove((caddr_t) (kva + pageoffset), sz, uio);
                    135:                if (error)
                    136:                        break;
                    137:                togo -= sz;
                    138:                baseva += chunksz;
                    139:
                    140:
                    141:                /*
                    142:                 * step 4: unmap the area of kernel memory
                    143:                 */
                    144:
                    145:                vm_map_lock(kernel_map);
1.7       chuck     146:                (void)uvm_unmap_remove(kernel_map, kva, kva+chunksz,
1.4       mrg       147:                    &dead_entries);
                    148:                vm_map_unlock(kernel_map);
                    149:
                    150:                if (dead_entries != NULL)
                    151:                        uvm_unmap_detach(dead_entries, AMAP_REFALL);
                    152:        }
                    153:
                    154:        /*
                    155:         * done
                    156:         */
1.1       mrg       157:
1.4       mrg       158:        return (error);
1.1       mrg       159: }

CVSweb <webmaster@jp.NetBSD.org>