Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/kern Make page loaning in pipes color aware.



details:   https://anonhg.NetBSD.org/src/rev/3f7af50ac660
branches:  trunk
changeset: 787669:3f7af50ac660
user:      matt <matt%NetBSD.org@localhost>
date:      Fri Jun 28 01:21:06 2013 +0000

description:
Make page loaning in pipes color aware.

diffstat:

 sys/kern/sys_pipe.c |  90 ++++++++++++++++++++++++++++------------------------
 1 files changed, 48 insertions(+), 42 deletions(-)

diffs (234 lines):

diff -r 20099faa523b -r 3f7af50ac660 sys/kern/sys_pipe.c
--- a/sys/kern/sys_pipe.c       Fri Jun 28 01:13:40 2013 +0000
+++ b/sys/kern/sys_pipe.c       Fri Jun 28 01:21:06 2013 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: sys_pipe.c,v 1.136 2012/05/16 09:41:11 martin Exp $    */
+/*     $NetBSD: sys_pipe.c,v 1.137 2013/06/28 01:21:06 matt Exp $      */
 
 /*-
  * Copyright (c) 2003, 2007, 2008, 2009 The NetBSD Foundation, Inc.
@@ -68,7 +68,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sys_pipe.c,v 1.136 2012/05/16 09:41:11 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sys_pipe.c,v 1.137 2013/06/28 01:21:06 matt Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -503,6 +503,7 @@
 
 #ifndef PIPE_NODIRECT
                if ((rpipe->pipe_state & PIPE_DIRECTR) != 0) {
+                       struct pipemapping * const rmap = &rpipe->pipe_map;
                        /*
                         * Direct copy, bypassing a kernel buffer.
                         */
@@ -511,12 +512,12 @@
 
                        KASSERT(rpipe->pipe_state & PIPE_DIRECTW);
 
-                       size = rpipe->pipe_map.cnt;
+                       size = rmap->cnt;
                        if (size > uio->uio_resid)
                                size = uio->uio_resid;
 
-                       va = (char *)rpipe->pipe_map.kva + rpipe->pipe_map.pos;
-                       gen = rpipe->pipe_map.egen;
+                       va = (char *)rmap->kva + rmap->pos;
+                       gen = rmap->egen;
                        mutex_exit(lock);
 
                        /*
@@ -529,9 +530,9 @@
                        if (error)
                                break;
                        nread += size;
-                       rpipe->pipe_map.pos += size;
-                       rpipe->pipe_map.cnt -= size;
-                       if (rpipe->pipe_map.cnt == 0) {
+                       rmap->pos += size;
+                       rmap->cnt -= size;
+                       if (rmap->cnt == 0) {
                                rpipe->pipe_state &= ~PIPE_DIRECTR;
                                cv_broadcast(&rpipe->pipe_wcv);
                        }
@@ -633,20 +634,19 @@
 static int
 pipe_loan_alloc(struct pipe *wpipe, int npages)
 {
-       vsize_t len;
+       struct pipemapping * const wmap = &wpipe->pipe_map;
+       const vsize_t len = ptoa(npages);
 
-       len = (vsize_t)npages << PAGE_SHIFT;
        atomic_add_int(&amountpipekva, len);
-       wpipe->pipe_map.kva = uvm_km_alloc(kernel_map, len, 0,
-           UVM_KMF_VAONLY | UVM_KMF_WAITVA);
-       if (wpipe->pipe_map.kva == 0) {
+       wmap->kva = uvm_km_alloc(kernel_map, len, 0,
+           UVM_KMF_COLORMATCH | UVM_KMF_VAONLY | UVM_KMF_WAITVA);
+       if (wmap->kva == 0) {
                atomic_add_int(&amountpipekva, -len);
                return (ENOMEM);
        }
 
-       wpipe->pipe_map.npages = npages;
-       wpipe->pipe_map.pgs = kmem_alloc(npages * sizeof(struct vm_page *),
-           KM_SLEEP);
+       wmap->npages = npages;
+       wmap->pgs = kmem_alloc(npages * sizeof(struct vm_page *), KM_SLEEP);
        return (0);
 }
 
@@ -656,16 +656,20 @@
 static void
 pipe_loan_free(struct pipe *wpipe)
 {
-       vsize_t len;
+       struct pipemapping * const wmap = &wpipe->pipe_map;
+       const vsize_t len = ptoa(wmap->npages);
 
-       len = (vsize_t)wpipe->pipe_map.npages << PAGE_SHIFT;
-       uvm_emap_remove(wpipe->pipe_map.kva, len);      /* XXX */
-       uvm_km_free(kernel_map, wpipe->pipe_map.kva, len, UVM_KMF_VAONLY);
-       wpipe->pipe_map.kva = 0;
+       uvm_emap_remove(wmap->kva, len);        /* XXX */
+       uvm_km_free(kernel_map, wmap->kva, len, UVM_KMF_VAONLY);
+       wmap->kva = 0;
        atomic_add_int(&amountpipekva, -len);
-       kmem_free(wpipe->pipe_map.pgs,
-           wpipe->pipe_map.npages * sizeof(struct vm_page *));
-       wpipe->pipe_map.pgs = NULL;
+       kmem_free(wmap->pgs, wmap->npages * sizeof(struct vm_page *));
+       wmap->pgs = NULL;
+#if 0
+       wmap->npages = 0;
+       wmap->pos = 0;
+       wmap->cnt = 0;
+#endif
 }
 
 /*
@@ -681,15 +685,17 @@
 static int
 pipe_direct_write(file_t *fp, struct pipe *wpipe, struct uio *uio)
 {
+       struct pipemapping * const wmap = &wpipe->pipe_map;
+       kmutex_t * const lock = wpipe->pipe_lock;
        struct vm_page **pgs;
        vaddr_t bbase, base, bend;
        vsize_t blen, bcnt;
        int error, npages;
        voff_t bpos;
-       kmutex_t *lock = wpipe->pipe_lock;
+       u_int starting_color;
 
        KASSERT(mutex_owned(wpipe->pipe_lock));
-       KASSERT(wpipe->pipe_map.cnt == 0);
+       KASSERT(wmap->cnt == 0);
 
        mutex_exit(lock);
 
@@ -710,18 +716,19 @@
        } else {
                bcnt = uio->uio_iov->iov_len;
        }
-       npages = blen >> PAGE_SHIFT;
+       npages = atop(blen);
+       starting_color = atop(base) & uvmexp.colormask;
 
        /*
         * Free the old kva if we need more pages than we have
         * allocated.
         */
-       if (wpipe->pipe_map.kva != 0 && npages > wpipe->pipe_map.npages)
+       if (wmap->kva != 0 && starting_color + npages > wmap->npages)
                pipe_loan_free(wpipe);
 
        /* Allocate new kva. */
-       if (wpipe->pipe_map.kva == 0) {
-               error = pipe_loan_alloc(wpipe, npages);
+       if (wmap->kva == 0) {
+               error = pipe_loan_alloc(wpipe, starting_color + npages);
                if (error) {
                        mutex_enter(lock);
                        return (error);
@@ -729,7 +736,7 @@
        }
 
        /* Loan the write buffer memory from writer process */
-       pgs = wpipe->pipe_map.pgs;
+       pgs = wmap->pgs + starting_color;
        error = uvm_loan(&uio->uio_vmspace->vm_map, base, blen,
                         pgs, UVM_LOAN_TOPAGE);
        if (error) {
@@ -739,12 +746,12 @@
        }
 
        /* Enter the loaned pages to KVA, produce new emap generation number. */
-       uvm_emap_enter(wpipe->pipe_map.kva, pgs, npages);
-       wpipe->pipe_map.egen = uvm_emap_produce();
+       uvm_emap_enter(wmap->kva + ptoa(starting_color), pgs, npages);
+       wmap->egen = uvm_emap_produce();
 
        /* Now we can put the pipe in direct write mode */
-       wpipe->pipe_map.pos = bpos;
-       wpipe->pipe_map.cnt = bcnt;
+       wmap->pos = bpos + ptoa(starting_color);
+       wmap->cnt = bcnt;
 
        /*
         * But before we can let someone do a direct read, we
@@ -798,13 +805,13 @@
                 * will deal with the error condition, returning short
                 * write, error, or restarting the write(2) as appropriate.
                 */
-               if (wpipe->pipe_map.cnt == bcnt) {
-                       wpipe->pipe_map.cnt = 0;
+               if (wmap->cnt == bcnt) {
+                       wmap->cnt = 0;
                        cv_broadcast(&wpipe->pipe_wcv);
                        return (error);
                }
 
-               bcnt -= wpipe->pipe_map.cnt;
+               bcnt -= wpipe->cnt;
        }
 
        uio->uio_resid -= bcnt;
@@ -816,7 +823,7 @@
                uio->uio_iovcnt--;
        }
 
-       wpipe->pipe_map.cnt = 0;
+       wmap->cnt = 0;
        return (error);
 }
 #endif /* !PIPE_NODIRECT */
@@ -909,7 +916,7 @@
                 */
                if ((uio->uio_iov->iov_len >= PIPE_MINDIRECT) &&
                    (fp->f_flag & FNONBLOCK) == 0 &&
-                   (wpipe->pipe_map.kva || (amountpipekva < limitpipekva))) {
+                   (wmap->kva || (amountpipekva < limitpipekva))) {
                        error = pipe_direct_write(fp, wpipe, uio);
 
                        /*
@@ -1047,7 +1054,7 @@
 
        /*
         * We have something to offer, wake up select/poll.
-        * wpipe->pipe_map.cnt is always 0 in this point (direct write
+        * wmap->cnt is always 0 in this point (direct write
         * is only done synchronously), so check only wpipe->pipe_buffer.cnt
         */
        if (bp->cnt)
@@ -1269,7 +1276,6 @@
        if (pipe->pipe_map.kva != 0) {
                pipe_loan_free(pipe);
                pipe->pipe_map.cnt = 0;
-               pipe->pipe_map.kva = 0;
                pipe->pipe_map.pos = 0;
                pipe->pipe_map.npages = 0;
        }



Home | Main Index | Thread Index | Old Index