Source-Changes-HG archive

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

[src/trunk]: src/sys remove experimental direct pipe code (using uvm_loan()) ...



details:   https://anonhg.NetBSD.org/src/rev/be0943942ac8
branches:  trunk
changeset: 973262:be0943942ac8
user:      jdolecek <jdolecek%NetBSD.org@localhost>
date:      Thu Jun 25 14:22:18 2020 +0000

description:
remove experimental direct pipe code (using uvm_loan()) I added in 2001 - it's
slower than the non-direct variant on MP systems, if anybody wants
to hack on this further it's available in Attic

diffstat:

 sys/kern/sys_pipe.c |  360 +---------------------------------------------------
 sys/sys/pipe.h      |   16 +--
 2 files changed, 5 insertions(+), 371 deletions(-)

diffs (truncated from 532 to 300 lines):

diff -r eda8a3d31a6b -r be0943942ac8 sys/kern/sys_pipe.c
--- a/sys/kern/sys_pipe.c       Thu Jun 25 14:08:48 2020 +0000
+++ b/sys/kern/sys_pipe.c       Thu Jun 25 14:22:18 2020 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: sys_pipe.c,v 1.148 2019/04/26 17:24:23 mlelstv Exp $   */
+/*     $NetBSD: sys_pipe.c,v 1.149 2020/06/25 14:22:18 jdolecek 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.148 2019/04/26 17:24:23 mlelstv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sys_pipe.c,v 1.149 2020/06/25 14:22:18 jdolecek Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -92,24 +92,6 @@
 #include <sys/atomic.h>
 #include <sys/pipe.h>
 
-/*
- * Use this to disable direct I/O and decrease the code size:
- * #define PIPE_NODIRECT
- */
-
-/* XXX Disabled for now; rare hangs switching between direct/buffered */        
-#define PIPE_NODIRECT
-
-#ifndef PIPE_NODIRECT
-#include <uvm/uvm.h>
-
-#if !defined(PMAP_DIRECT)
-#  define PIPE_NODIRECT                /* Direct map interface not available */
-#endif
-
-bool pipe_direct = true;
-#endif
-
 static int     pipe_read(file_t *, off_t *, struct uio *, kauth_cred_t, int);
 static int     pipe_write(file_t *, off_t *, struct uio *, kauth_cred_t, int);
 static int     pipe_close(file_t *);
@@ -159,19 +141,10 @@
 static int     pipelock(struct pipe *, bool);
 static inline void pipeunlock(struct pipe *);
 static void    pipeselwakeup(struct pipe *, struct pipe *, int);
-#ifndef PIPE_NODIRECT
-static int     pipe_direct_write(file_t *, struct pipe *, struct uio *);
-#endif
 static int     pipespace(struct pipe *, int);
 static int     pipe_ctor(void *, void *, int);
 static void    pipe_dtor(void *, void *);
 
-#ifndef PIPE_NODIRECT
-static int     pipe_loan_alloc(struct pipe *, int);
-static void    pipe_loan_free(struct pipe *);
-static int     pipe_direct_process_read(void *, size_t, void *);
-#endif /* PIPE_NODIRECT */
-
 static pool_cache_t    pipe_wr_cache;
 static pool_cache_t    pipe_rd_cache;
 
@@ -439,16 +412,6 @@
        fownsignal(sigp->pipe_pgid, SIGIO, code, band, selp);
 }
 
-#ifndef PIPE_NODIRECT
-static int
-pipe_direct_process_read(void *va, size_t len, void *arg)
-{
-       struct uio *uio = (struct uio *)arg;
-
-       return uiomove(va, len, uio);
-}
-#endif
-
 static int
 pipe_read(file_t *fp, off_t *offset, struct uio *uio, kauth_cred_t cred,
     int flags)
@@ -507,45 +470,6 @@
                        continue;
                }
 
-#ifndef PIPE_NODIRECT
-               if ((rpipe->pipe_state & PIPE_DIRECTR) != 0) {
-                       struct pipemapping * const rmap = &rpipe->pipe_map;
-                       voff_t pgoff;
-                       u_int pgst, npages;
-
-                       /*
-                        * Direct copy, bypassing a kernel buffer.
-                        */
-                       KASSERT(rpipe->pipe_state & PIPE_DIRECTW);
-
-                       size = MIN(rmap->cnt, uio->uio_resid);
-
-                       if (size > 0) {
-                               KASSERT(size > 0);
-                               mutex_exit(lock);
-
-                               pgst = rmap->pos >> PAGE_SHIFT;
-                               pgoff = rmap->pos & PAGE_MASK;
-                               npages = (size + pgoff + PAGE_SIZE - 1) >> PAGE_SHIFT;
-                               KASSERTMSG(npages > 0 && (pgst + npages) <= rmap->npages, "npages %u pgst %u rmap->npages %u", npages, pgst, rmap->npages);
-                               
-                               error = uvm_direct_process(&rmap->pgs[pgst], npages,
-                                   pgoff, size, pipe_direct_process_read, uio);
-                               mutex_enter(lock);
-
-                               nread += size;
-                               rmap->pos += size;
-                               rmap->cnt -= size;
-                       }
-
-                       if (rmap->cnt == 0) {
-                               rpipe->pipe_state &= ~PIPE_DIRECTR;
-                               cv_broadcast(&rpipe->pipe_wcv);
-                       }
-
-                       continue;
-               }
-#endif
                /*
                 * Break if some data was read.
                 */
@@ -574,12 +498,6 @@
                 */
                pipeunlock(rpipe);
 
-               /*
-                * Re-check to see if more direct writes are pending.
-                */
-               if ((rpipe->pipe_state & PIPE_DIRECTR) != 0)
-                       goto again;
-
 #if 1   /* XXX (dsl) I'm sure these aren't needed here ... */
                /*
                 * We want to read more, wake up select/poll.
@@ -634,189 +552,6 @@
        return (error);
 }
 
-#ifndef PIPE_NODIRECT
-/*
- * Allocate structure for loan transfer.
- */
-static int
-pipe_loan_alloc(struct pipe *wpipe, int npages)
-{
-       struct pipemapping * const wmap = &wpipe->pipe_map;
-
-       KASSERT(wmap->npages == 0);
-
-       if (npages > wmap->maxpages) {
-               pipe_loan_free(wpipe);
-
-               wmap->pgs = kmem_alloc(npages * sizeof(struct vm_page *), KM_NOSLEEP);
-               if (wmap->pgs == NULL)
-                       return ENOMEM;
-               wmap->maxpages = npages;
-       }
-
-       wmap->npages = npages;
-
-       return (0);
-}
-
-/*
- * Free resources allocated for loan transfer.
- */
-static void
-pipe_loan_free(struct pipe *wpipe)
-{
-       struct pipemapping * const wmap = &wpipe->pipe_map;
-
-       if (wmap->maxpages > 0) {
-               kmem_free(wmap->pgs, wmap->maxpages * sizeof(struct vm_page *));
-               wmap->pgs = NULL;
-               wmap->maxpages = 0;
-       }
-
-       wmap->npages = 0;
-       wmap->pos = 0;
-       wmap->cnt = 0;
-}
-
-/*
- * NetBSD direct write, using uvm_loan() mechanism.
- * This implements the pipe buffer write mechanism.  Note that only
- * a direct write OR a normal pipe write can be pending at any given time.
- * If there are any characters in the pipe buffer, the direct write will
- * be deferred until the receiving process grabs all of the bytes from
- * the pipe buffer.  Then the direct mapping write is set-up.
- *
- * Called with the long-term pipe lock held.
- */
-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;
-       vaddr_t bbase, base, bend;
-       vsize_t blen, bcnt;
-       int error, npages;
-       voff_t bpos;
-
-       KASSERT(mutex_owned(lock));
-       KASSERT(wmap->cnt == 0);
-
-       mutex_exit(lock);
-
-       /*
-        * Handle first PIPE_DIRECT_CHUNK bytes of buffer. Deal with buffers
-        * not aligned to PAGE_SIZE.
-        */
-       bbase = (vaddr_t)uio->uio_iov->iov_base;
-       base = trunc_page(bbase);
-       bend = round_page(bbase + uio->uio_iov->iov_len);
-       blen = bend - base;
-       bpos = bbase - base;
-
-       if (blen > PIPE_DIRECT_CHUNK) {
-               blen = PIPE_DIRECT_CHUNK;
-               bend = base + blen;
-               bcnt = PIPE_DIRECT_CHUNK - bpos;
-       } else {
-               bcnt = uio->uio_iov->iov_len;
-       }
-       npages = atop(blen);
-
-       KASSERT((wpipe->pipe_state & (PIPE_DIRECTW | PIPE_DIRECTR)) == 0);
-       KASSERT(wmap->npages == 0);
-
-       /* Make sure page array is big enough */
-       error = pipe_loan_alloc(wpipe, npages);
-       if (error) {
-               mutex_enter(lock);
-               return (error);
-       }
-
-       /* Loan the write buffer memory from writer process */
-       error = uvm_loan(&uio->uio_vmspace->vm_map, base, blen,
-                        wmap->pgs, UVM_LOAN_TOPAGE);
-       if (error) {
-               pipe_loan_free(wpipe);
-               mutex_enter(lock);
-               return (ENOMEM); /* so that caller fallback to ordinary write */
-       }
-
-       /* Now we can put the pipe in direct write mode */
-       wmap->pos = bpos;
-       wmap->cnt = bcnt;
-
-       /*
-        * But before we can let someone do a direct read, we
-        * have to wait until the pipe is drained.  Release the
-        * pipe lock while we wait.
-        */
-       mutex_enter(lock);
-       wpipe->pipe_state |= PIPE_DIRECTW;
-       pipeunlock(wpipe);
-
-       while (error == 0 && wpipe->pipe_buffer.cnt > 0) {
-               cv_broadcast(&wpipe->pipe_rcv);
-               error = cv_wait_sig(&wpipe->pipe_wcv, lock);
-               if (error == 0 && wpipe->pipe_state & PIPE_EOF)
-                       error = EPIPE;
-       }
-
-       /* Pipe is drained; next read will off the direct buffer */
-       wpipe->pipe_state |= PIPE_DIRECTR;
-
-       /* Wait until the reader is done */
-       while (error == 0 && (wpipe->pipe_state & PIPE_DIRECTR)) {
-               cv_broadcast(&wpipe->pipe_rcv);
-               pipeselwakeup(wpipe, wpipe, POLL_IN);
-               error = cv_wait_sig(&wpipe->pipe_wcv, lock);
-               if (error == 0 && wpipe->pipe_state & PIPE_EOF)
-                       error = EPIPE;
-       }
-
-       /* Take pipe out of direct write mode */
-       wpipe->pipe_state &= ~(PIPE_DIRECTW | PIPE_DIRECTR);
-
-       /* Acquire the pipe lock and cleanup */
-       (void)pipelock(wpipe, false);
-
-       mutex_exit(lock);
-       /* XXX what happens if the writer process exits without waiting for reader?
-        * XXX FreeBSD does a clone in this case */
-       uvm_unloan(wmap->pgs, npages, UVM_LOAN_TOPAGE);
-       mutex_enter(lock);
-
-       if (error) {
-               pipeselwakeup(wpipe, wpipe, POLL_ERR);
-
-               /*
-                * If nothing was read from what we offered, return error
-                * straight on. Otherwise update uio resid first. Caller



Home | Main Index | Thread Index | Old Index