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