Module Name:    src
Committed By:   matt
Date:           Fri Jun 28 01:21:06 UTC 2013

Modified Files:
        src/sys/kern: sys_pipe.c

Log Message:
Make page loaning in pipes color aware.


To generate a diff of this commit:
cvs rdiff -u -r1.136 -r1.137 src/sys/kern/sys_pipe.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/kern/sys_pipe.c
diff -u src/sys/kern/sys_pipe.c:1.136 src/sys/kern/sys_pipe.c:1.137
--- src/sys/kern/sys_pipe.c:1.136	Wed May 16 09:41:11 2012
+++ src/sys/kern/sys_pipe.c	Fri Jun 28 01:21:06 2013
@@ -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 @@ again:
 
 #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 @@ again:
 
 			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 @@ again:
 			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 @@ unlocked_error:
 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 @@ pipe_loan_alloc(struct pipe *wpipe, int 
 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 @@ pipe_loan_free(struct pipe *wpipe)
 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 @@ pipe_direct_write(file_t *fp, struct pip
 	} 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 @@ pipe_direct_write(file_t *fp, struct pip
 	}
 
 	/* 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 @@ pipe_direct_write(file_t *fp, struct pip
 	}
 
 	/* 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 @@ pipe_direct_write(file_t *fp, struct pip
 		 * 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 @@ pipe_direct_write(file_t *fp, struct pip
 		uio->uio_iovcnt--;
 	}
 
-	wpipe->pipe_map.cnt = 0;
+	wmap->cnt = 0;
 	return (error);
 }
 #endif /* !PIPE_NODIRECT */
@@ -909,7 +916,7 @@ pipe_write(file_t *fp, off_t *offset, st
 		 */
 		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 @@ pipe_write(file_t *fp, off_t *offset, st
 
 	/*
 	 * 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 @@ pipe_free_kmem(struct pipe *pipe)
 	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;
 	}

Reply via email to