Module Name: src
Committed By: matt
Date: Wed May 25 23:58:51 UTC 2011
Modified Files:
src/sys/arch/mips/mips [matt-nb5-mips64]: bus_dma.c
bus_space_alignstride_chipdep.c cache.c pmap.c vm_machdep.c
src/sys/kern [matt-nb5-mips64]: kern_malloc_debug.c kern_verifiedexec.c
sys_pipe.c uipc_socket.c
src/sys/miscfs/genfs [matt-nb5-mips64]: genfs_io.c
src/sys/sys [matt-nb5-mips64]: socketvar.h
src/sys/uvm [matt-nb5-mips64]: uvm_aobj.c uvm_extern.h uvm_fault.c
uvm_km.c uvm_map.c uvm_page.h uvm_pager.c uvm_pglist.c uvm_vnode.c
Log Message:
Make uvm_map recognize UVM_FLAG_COLORMATCH which tells uvm_map that the
'align' argument specifies the starting color of the KVA range to be returned.
When calling uvm_km_alloc with UVM_KMF_VAONLY, also specify the starting
color of the kva range returned (UMV_KMF_COLORMATCH) and pass those to
uvm_map.
In uvm_pglistalloc, make sure the pages being returned have sequentially
advancing colors (so they can be mapped in a contiguous address range).
Add a few missing UVM_FLAG_COLORMATCH flags to uvm_pagealloc calls.
Make the socket and pipe loan color-safe.
Make the mips pmap enforce strict page color (color(VA) == color(PA)).
To generate a diff of this commit:
cvs rdiff -u -r1.22.16.18 -r1.22.16.19 src/sys/arch/mips/mips/bus_dma.c
cvs rdiff -u -r1.10.18.12 -r1.10.18.13 \
src/sys/arch/mips/mips/bus_space_alignstride_chipdep.c
cvs rdiff -u -r1.33.96.4 -r1.33.96.5 src/sys/arch/mips/mips/cache.c
cvs rdiff -u -r1.179.16.28 -r1.179.16.29 src/sys/arch/mips/mips/pmap.c
cvs rdiff -u -r1.121.6.1.2.19 -r1.121.6.1.2.20 \
src/sys/arch/mips/mips/vm_machdep.c
cvs rdiff -u -r1.20 -r1.20.12.1 src/sys/kern/kern_malloc_debug.c
cvs rdiff -u -r1.111.4.1 -r1.111.4.1.4.1 src/sys/kern/kern_verifiedexec.c
cvs rdiff -u -r1.103.4.5 -r1.103.4.5.4.1 src/sys/kern/sys_pipe.c
cvs rdiff -u -r1.177.4.2.2.1.2.1 -r1.177.4.2.2.1.2.2 \
src/sys/kern/uipc_socket.c
cvs rdiff -u -r1.13.4.2.4.2 -r1.13.4.2.4.3 src/sys/miscfs/genfs/genfs_io.c
cvs rdiff -u -r1.116.4.2 -r1.116.4.2.4.1 src/sys/sys/socketvar.h
cvs rdiff -u -r1.104 -r1.104.10.1 src/sys/uvm/uvm_aobj.c
cvs rdiff -u -r1.148.4.2.4.1 -r1.148.4.2.4.2 src/sys/uvm/uvm_extern.h
cvs rdiff -u -r1.125.6.1.4.1 -r1.125.6.1.4.2 src/sys/uvm/uvm_fault.c
cvs rdiff -u -r1.101.4.2.4.3 -r1.101.4.2.4.4 src/sys/uvm/uvm_km.c
cvs rdiff -u -r1.263.4.3.4.3 -r1.263.4.3.4.4 src/sys/uvm/uvm_map.c
cvs rdiff -u -r1.55.14.2 -r1.55.14.3 src/sys/uvm/uvm_page.h
cvs rdiff -u -r1.92 -r1.92.18.1 src/sys/uvm/uvm_pager.c
cvs rdiff -u -r1.42.16.6 -r1.42.16.7 src/sys/uvm/uvm_pglist.c
cvs rdiff -u -r1.90 -r1.90.28.1 src/sys/uvm/uvm_vnode.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/arch/mips/mips/bus_dma.c
diff -u src/sys/arch/mips/mips/bus_dma.c:1.22.16.18 src/sys/arch/mips/mips/bus_dma.c:1.22.16.19
--- src/sys/arch/mips/mips/bus_dma.c:1.22.16.18 Fri Apr 29 08:26:23 2011
+++ src/sys/arch/mips/mips/bus_dma.c Wed May 25 23:58:47 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: bus_dma.c,v 1.22.16.18 2011/04/29 08:26:23 matt Exp $ */
+/* bus_dma.c,v 1.22.16.18 2011/04/29 08:26:23 matt Exp */
/*-
* Copyright (c) 1997, 1998, 2001 The NetBSD Foundation, Inc.
@@ -32,7 +32,7 @@
#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
-__KERNEL_RCSID(0, "$NetBSD: bus_dma.c,v 1.22.16.18 2011/04/29 08:26:23 matt Exp $");
+__KERNEL_RCSID(0, "bus_dma.c,v 1.22.16.18 2011/04/29 08:26:23 matt Exp");
#include <sys/param.h>
#include <sys/systm.h>
@@ -934,6 +934,7 @@
" address 0x%"PRIxPADDR"\n", curaddr);
panic("_bus_dmamem_alloc");
}
+ KASSERT((atop(curaddr - lastaddr) & uvmexp.colormask) == 1);
#endif
if (curaddr == (lastaddr + PAGE_SIZE))
segs[curseg].ds_len += PAGE_SIZE;
@@ -1020,7 +1021,9 @@
size = round_page(size);
- va = uvm_km_alloc(kernel_map, size, 0, UVM_KMF_VAONLY | kmflags);
+ va = uvm_km_alloc(kernel_map, size,
+ atop(segs[0].ds_addr) & uvmexp.colormask,
+ UVM_KMF_COLORMATCH | UVM_KMF_VAONLY | kmflags);
if (va == 0)
return (ENOMEM);
Index: src/sys/arch/mips/mips/bus_space_alignstride_chipdep.c
diff -u src/sys/arch/mips/mips/bus_space_alignstride_chipdep.c:1.10.18.12 src/sys/arch/mips/mips/bus_space_alignstride_chipdep.c:1.10.18.13
--- src/sys/arch/mips/mips/bus_space_alignstride_chipdep.c:1.10.18.12 Thu Jan 14 05:02:38 2010
+++ src/sys/arch/mips/mips/bus_space_alignstride_chipdep.c Wed May 25 23:58:47 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: bus_space_alignstride_chipdep.c,v 1.10.18.12 2010/01/14 05:02:38 cliff Exp $ */
+/* bus_space_alignstride_chipdep.c,v 1.10.18.12 2010/01/14 05:02:38 cliff Exp */
/*-
* Copyright (c) 1998, 2000, 2001 The NetBSD Foundation, Inc.
@@ -81,7 +81,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: bus_space_alignstride_chipdep.c,v 1.10.18.12 2010/01/14 05:02:38 cliff Exp $");
+__KERNEL_RCSID(0, "bus_space_alignstride_chipdep.c,v 1.10.18.12 2010/01/14 05:02:38 cliff Exp");
#ifdef CHIP_EXTENT
#include <sys/extent.h>
@@ -759,8 +759,9 @@
int s;
size = round_page((addr % PAGE_SIZE) + size);
- va = uvm_km_alloc(kernel_map, size, PAGE_SIZE,
- UVM_KMF_VAONLY | UVM_KMF_NOWAIT);
+ va = uvm_km_alloc(kernel_map, size,
+ atop(addr) & uvmexp.colormask,
+ UVM_KMF_COLORMATCH | UVM_KMF_VAONLY | UVM_KMF_NOWAIT);
if (va == 0)
return ENOMEM;
Index: src/sys/arch/mips/mips/cache.c
diff -u src/sys/arch/mips/mips/cache.c:1.33.96.4 src/sys/arch/mips/mips/cache.c:1.33.96.5
--- src/sys/arch/mips/mips/cache.c:1.33.96.4 Fri Apr 29 08:26:23 2011
+++ src/sys/arch/mips/mips/cache.c Wed May 25 23:58:47 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: cache.c,v 1.33.96.4 2011/04/29 08:26:23 matt Exp $ */
+/* cache.c,v 1.33.96.4 2011/04/29 08:26:23 matt Exp */
/*
* Copyright 2001, 2002 Wasabi Systems, Inc.
@@ -68,7 +68,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cache.c,v 1.33.96.4 2011/04/29 08:26:23 matt Exp $");
+__KERNEL_RCSID(0, "cache.c,v 1.33.96.4 2011/04/29 08:26:23 matt Exp");
#include "opt_cputype.h"
#include "opt_mips_cache.h"
@@ -931,7 +931,7 @@
mci->mci_pdcache_size =
mci->mci_pdcache_way_size * mci->mci_pdcache_ways;
mci->mci_pdcache_way_mask = mci->mci_pdcache_way_size - 1;
- uvmexp.ncolors = atop(mci->mci_pdcache_size) / mci->mci_pdcache_ways;
+ uvmexp.ncolors = atop(mci->mci_pdcache_way_size);
break;
}
@@ -959,6 +959,8 @@
mci->mci_picache_size =
mci->mci_picache_way_size * mci->mci_picache_ways;
mci->mci_picache_way_mask = mci->mci_picache_way_size - 1;
+ if (uvmexp.ncolors < atop(mci->mci_picache_way_size))
+ uvmexp.ncolors = atop(mci->mci_picache_way_size);
break;
}
Index: src/sys/arch/mips/mips/pmap.c
diff -u src/sys/arch/mips/mips/pmap.c:1.179.16.28 src/sys/arch/mips/mips/pmap.c:1.179.16.29
--- src/sys/arch/mips/mips/pmap.c:1.179.16.28 Fri Apr 29 08:26:29 2011
+++ src/sys/arch/mips/mips/pmap.c Wed May 25 23:58:48 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: pmap.c,v 1.179.16.28 2011/04/29 08:26:29 matt Exp $ */
+/* pmap.c,v 1.179.16.28 2011/04/29 08:26:29 matt Exp */
/*-
* Copyright (c) 1998, 2001 The NetBSD Foundation, Inc.
@@ -67,7 +67,7 @@
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.179.16.28 2011/04/29 08:26:29 matt Exp $");
+__KERNEL_RCSID(0, "pmap.c,v 1.179.16.28 2011/04/29 08:26:29 matt Exp");
/*
* Manages physical address maps.
@@ -739,15 +739,17 @@
*/
if (mips_avail_end > MIPS_KSEG1_START - MIPS_KSEG0_START) {
curcpu()->ci_pmap_dstbase = uvm_km_alloc(kernel_map,
- uvmexp.ncolors * PAGE_SIZE, 0, UVM_KMF_VAONLY);
+ uvmexp.ncolors * PAGE_SIZE, 0,
+ UVM_KMF_COLORMATCH | UVM_KMF_VAONLY);
KASSERT(curcpu()->ci_pmap_dstbase);
curcpu()->ci_pmap_srcbase = uvm_km_alloc(kernel_map,
- uvmexp.ncolors * PAGE_SIZE, 0, UVM_KMF_VAONLY);
+ uvmexp.ncolors * PAGE_SIZE, 0,
+ UVM_KMF_COLORMATCH | UVM_KMF_VAONLY);
KASSERT(curcpu()->ci_pmap_srcbase);
}
#endif
-#ifdef MIPS3
+#if defined(MIPS3) && 0
if (MIPS_HAS_R4K_MMU) {
/*
* XXX
@@ -1361,9 +1363,12 @@
#ifdef DEBUG
if (pmapdebug & (PDB_FOLLOW|PDB_ENTER))
printf("pmap_enter(%p, %#"PRIxVADDR", %#"PRIxPADDR", %x, %x)\n",
- pmap, va, pa, prot, wired);
+ pmap, va, pa, prot, flags);
#endif
const bool good_color = PMAP_PAGE_COLOROK_P(pa, va);
+ KASSERTMSG(good_color,
+ ("%s(%p, %#"PRIxVADDR", %#"PRIxPADDR", %x, %x): color mismatch\n",
+ __func__, pmap, va, pa, prot, flags));
if (pmap == pmap_kernel()) {
PMAP_COUNT(kernel_mappings);
if (!good_color)
@@ -1622,8 +1627,12 @@
printf("pmap_kenter_pa(%#"PRIxVADDR", %#"PRIxPADDR", %x)\n", va, pa, prot);
#endif
PMAP_COUNT(kenter_pa);
- if (!PMAP_PAGE_COLOROK_P(pa, va) && managed)
+ KASSERTMSG(!managed || PMAP_PAGE_COLOROK_P(pa, va),
+ ("%s(%#"PRIxVADDR", %#"PRIxPADDR", %x): color mismatch\n",
+ __func__, va, pa, prot));
+ if (!PMAP_PAGE_COLOROK_P(pa, va) && managed) {
PMAP_COUNT(kenter_pa_bad);
+ }
if (!managed)
PMAP_COUNT(kenter_pa_unmanaged);
Index: src/sys/arch/mips/mips/vm_machdep.c
diff -u src/sys/arch/mips/mips/vm_machdep.c:1.121.6.1.2.19 src/sys/arch/mips/mips/vm_machdep.c:1.121.6.1.2.20
--- src/sys/arch/mips/mips/vm_machdep.c:1.121.6.1.2.19 Fri Apr 29 08:26:31 2011
+++ src/sys/arch/mips/mips/vm_machdep.c Wed May 25 23:58:48 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: vm_machdep.c,v 1.121.6.1.2.19 2011/04/29 08:26:31 matt Exp $ */
+/* vm_machdep.c,v 1.121.6.1.2.19 2011/04/29 08:26:31 matt Exp */
/*
* Copyright (c) 1988 University of Utah.
@@ -39,7 +39,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: vm_machdep.c,v 1.121.6.1.2.19 2011/04/29 08:26:31 matt Exp $");
+__KERNEL_RCSID(0, "vm_machdep.c,v 1.121.6.1.2.19 2011/04/29 08:26:31 matt Exp");
#include "opt_ddb.h"
#include "opt_coredump.h"
@@ -366,12 +366,6 @@
}
#endif
-static struct evcnt evcnt_vmapbuf =
- EVCNT_INITIALIZER(EVCNT_TYPE_MISC, NULL, "vmapbuf", "calls");
-static struct evcnt evcnt_vmapbuf_adjustments =
- EVCNT_INITIALIZER(EVCNT_TYPE_MISC, &evcnt_vmapbuf,
- "vmapbuf", "adjustments");
-
/*
* Map a user I/O request into kernel virtual address space.
*/
@@ -383,21 +377,15 @@
vaddr_t kva; /* Kernel VA (new to) */
paddr_t pa; /* physical address */
vsize_t off;
- vsize_t coloroff;
if ((bp->b_flags & B_PHYS) == 0)
panic("vmapbuf");
- evcnt_vmapbuf.ev_count++;
uva = mips_trunc_page(bp->b_saveaddr = bp->b_data);
- coloroff = uva & ptoa(uvmexp.colormask);
- if (coloroff)
- evcnt_vmapbuf_adjustments.ev_count++;
off = (vaddr_t)bp->b_data - uva;
len = mips_round_page(off + len);
- kva = uvm_km_alloc(phys_map, len + coloroff, ptoa(uvmexp.ncolors),
- UVM_KMF_VAONLY | UVM_KMF_WAITVA);
- kva += coloroff;
+ kva = uvm_km_alloc(phys_map, len, atop(uva) & uvmexp.colormask,
+ UVM_FLAG_COLORMATCH | UVM_KMF_VAONLY | UVM_KMF_WAITVA);
bp->b_data = (void *)(kva + off);
upmap = vm_map_pmap(&bp->b_proc->p_vmspace->vm_map);
do {
@@ -420,18 +408,16 @@
{
vaddr_t kva;
vsize_t off;
- vsize_t coloroff;
if ((bp->b_flags & B_PHYS) == 0)
panic("vunmapbuf");
kva = mips_trunc_page(bp->b_data);
- coloroff = kva & ptoa(uvmexp.colormask);
off = (vaddr_t)bp->b_data - kva;
len = mips_round_page(off + len);
pmap_remove(vm_map_pmap(phys_map), kva, kva + len);
pmap_update(pmap_kernel());
- uvm_km_free(phys_map, kva - coloroff, len + coloroff, UVM_KMF_VAONLY);
+ uvm_km_free(phys_map, kva, len, UVM_KMF_VAONLY);
bp->b_data = bp->b_saveaddr;
bp->b_saveaddr = NULL;
}
Index: src/sys/kern/kern_malloc_debug.c
diff -u src/sys/kern/kern_malloc_debug.c:1.20 src/sys/kern/kern_malloc_debug.c:1.20.12.1
--- src/sys/kern/kern_malloc_debug.c:1.20 Thu Aug 7 01:40:21 2008
+++ src/sys/kern/kern_malloc_debug.c Wed May 25 23:58:48 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: kern_malloc_debug.c,v 1.20 2008/08/07 01:40:21 matt Exp $ */
+/* kern_malloc_debug.c,v 1.20 2008/08/07 01:40:21 matt Exp */
/*
* Copyright (c) 1999, 2000 Artur Grabowski <[email protected]>
@@ -56,7 +56,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_malloc_debug.c,v 1.20 2008/08/07 01:40:21 matt Exp $");
+__KERNEL_RCSID(0, "kern_malloc_debug.c,v 1.20 2008/08/07 01:40:21 matt Exp");
#include <sys/param.h>
#include <sys/proc.h>
@@ -240,7 +240,7 @@
offset = va - vm_map_min(kernel_map);
for (;;) {
- pg = uvm_pagealloc(NULL, offset, NULL, 0);
+ pg = uvm_pagealloc(NULL, offset, NULL, UVM_FLAG_COLORMATCH);
if (pg) {
pg->flags &= ~PG_BUSY; /* new page */
UVM_PAGE_OWN(pg, NULL);
Index: src/sys/kern/kern_verifiedexec.c
diff -u src/sys/kern/kern_verifiedexec.c:1.111.4.1 src/sys/kern/kern_verifiedexec.c:1.111.4.1.4.1
--- src/sys/kern/kern_verifiedexec.c:1.111.4.1 Thu Dec 18 00:56:27 2008
+++ src/sys/kern/kern_verifiedexec.c Wed May 25 23:58:48 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: kern_verifiedexec.c,v 1.111.4.1 2008/12/18 00:56:27 snj Exp $ */
+/* kern_verifiedexec.c,v 1.111.4.1 2008/12/18 00:56:27 snj Exp */
/*-
* Copyright (c) 2005, 2006 Elad Efrat <[email protected]>
@@ -29,7 +29,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_verifiedexec.c,v 1.111.4.1 2008/12/18 00:56:27 snj Exp $");
+__KERNEL_RCSID(0, "kern_verifiedexec.c,v 1.111.4.1 2008/12/18 00:56:27 snj Exp");
#include "opt_veriexec.h"
@@ -765,7 +765,8 @@
ctx = kmem_alloc(vfe->ops->context_size, KM_SLEEP);
fp = kmem_alloc(vfe->ops->hash_len, KM_SLEEP);
- kva = uvm_km_alloc(kernel_map, PAGE_SIZE, 0, UVM_KMF_VAONLY | UVM_KMF_WAITVA);
+ kva = uvm_km_alloc(kernel_map, PAGE_SIZE, VM_PAGE_TO_COLOR(pg),
+ UVM_KMF_COLORMATCH | UVM_KMF_VAONLY | UVM_KMF_WAITVA);
pmap_kenter_pa(kva, VM_PAGE_TO_PHYS(pg), VM_PROT_READ);
pmap_update(pmap_kernel());
Index: src/sys/kern/sys_pipe.c
diff -u src/sys/kern/sys_pipe.c:1.103.4.5 src/sys/kern/sys_pipe.c:1.103.4.5.4.1
--- src/sys/kern/sys_pipe.c:1.103.4.5 Sat Apr 4 23:36:27 2009
+++ src/sys/kern/sys_pipe.c Wed May 25 23:58:48 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: sys_pipe.c,v 1.103.4.5 2009/04/04 23:36:27 snj Exp $ */
+/* sys_pipe.c,v 1.103.4.5 2009/04/04 23:36:27 snj 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.103.4.5 2009/04/04 23:36:27 snj Exp $");
+__KERNEL_RCSID(0, "sys_pipe.c,v 1.103.4.5 2009/04/04 23:36:27 snj Exp");
#include <sys/param.h>
#include <sys/systm.h>
@@ -508,6 +508,7 @@
#ifndef PIPE_NODIRECT
if ((rpipe->pipe_state & PIPE_DIRECTR) != 0) {
+ struct pipemapping * const rmap = &rpipe->pipe_map;
/*
* Direct copy, bypassing a kernel buffer.
*/
@@ -515,20 +516,20 @@
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;
+ va = (char *)rmap->kva + rmap->koff + rmap->pos;
mutex_exit(lock);
error = uiomove(va, size, uio);
mutex_enter(lock);
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);
}
@@ -621,20 +622,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);
}
@@ -644,15 +644,19 @@
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_km_free(kernel_map, wpipe->pipe_map.kva, len, UVM_KMF_VAONLY);
- wpipe->pipe_map.kva = 0;
+ 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
}
/*
@@ -668,15 +672,17 @@
static int
pipe_direct_write(struct file *fp, struct pipe *wpipe, struct uio *uio)
{
+ struct pipemapping * const wmap = &wpipe->pipe_map;
+ kmutex_t * const lock = wpipe->pipe_lock;
int error, npages, j;
struct vm_page **pgs;
vaddr_t bbase, kva, base, bend;
vsize_t blen, bcnt;
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);
@@ -697,18 +703,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);
@@ -716,7 +723,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) {
@@ -726,15 +733,15 @@
}
/* Enter the loaned pages to kva */
- kva = wpipe->pipe_map.kva;
+ kva = wmap->kva + ptoa(starting_color);
for (j = 0; j < npages; j++, kva += PAGE_SIZE) {
pmap_kenter_pa(kva, VM_PAGE_TO_PHYS(pgs[j]), VM_PROT_READ);
}
pmap_update(pmap_kernel());
/* 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
@@ -772,7 +779,7 @@
mutex_exit(lock);
if (pgs != NULL) {
- pmap_kremove(wpipe->pipe_map.kva, blen);
+ pmap_kremove(wmap->kva, blen);
pmap_update(pmap_kernel());
uvm_unloan(pgs, npages, UVM_LOAN_TOPAGE);
}
@@ -789,13 +796,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;
@@ -807,7 +814,7 @@
uio->uio_iovcnt--;
}
- wpipe->pipe_map.cnt = 0;
+ wmap->cnt = 0;
return (error);
}
#endif /* !PIPE_NODIRECT */
@@ -1240,7 +1247,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;
}
Index: src/sys/kern/uipc_socket.c
diff -u src/sys/kern/uipc_socket.c:1.177.4.2.2.1.2.1 src/sys/kern/uipc_socket.c:1.177.4.2.2.1.2.2
--- src/sys/kern/uipc_socket.c:1.177.4.2.2.1.2.1 Wed Apr 21 00:28:18 2010
+++ src/sys/kern/uipc_socket.c Wed May 25 23:58:48 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: uipc_socket.c,v 1.177.4.2.2.1.2.1 2010/04/21 00:28:18 matt Exp $ */
+/* uipc_socket.c,v 1.177.4.2.2.1.2.1 2010/04/21 00:28:18 matt Exp */
/*-
* Copyright (c) 2002, 2007, 2008, 2009 The NetBSD Foundation, Inc.
@@ -63,7 +63,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uipc_socket.c,v 1.177.4.2.2.1.2.1 2010/04/21 00:28:18 matt Exp $");
+__KERNEL_RCSID(0, "uipc_socket.c,v 1.177.4.2.2.1.2.1 2010/04/21 00:28:18 matt Exp");
#include "opt_sock_counters.h"
#include "opt_sosend_loan.h"
@@ -199,7 +199,7 @@
*/
vaddr_t
-sokvaalloc(vsize_t len, struct socket *so)
+sokvaalloc(vaddr_t sva, vsize_t len, struct socket *so)
{
vaddr_t lva;
@@ -214,7 +214,8 @@
* allocate kva.
*/
- lva = uvm_km_alloc(kernel_map, len, 0, UVM_KMF_VAONLY | UVM_KMF_WAITVA);
+ lva = uvm_km_alloc(kernel_map, len, atop(sva) & uvmexp.colormask,
+ UVM_KMF_COLORMATCH | UVM_KMF_VAONLY | UVM_KMF_WAITVA);
if (lva == 0) {
sokvaunreserve(len);
return (0);
@@ -362,7 +363,7 @@
KASSERT(npgs <= M_EXT_MAXPAGES);
- lva = sokvaalloc(len, so);
+ lva = sokvaalloc(sva, len, so);
if (lva == 0)
return 0;
Index: src/sys/miscfs/genfs/genfs_io.c
diff -u src/sys/miscfs/genfs/genfs_io.c:1.13.4.2.4.2 src/sys/miscfs/genfs/genfs_io.c:1.13.4.2.4.3
--- src/sys/miscfs/genfs/genfs_io.c:1.13.4.2.4.2 Fri May 20 08:11:28 2011
+++ src/sys/miscfs/genfs/genfs_io.c Wed May 25 23:58:48 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: genfs_io.c,v 1.13.4.2.4.2 2011/05/20 08:11:28 matt Exp $ */
+/* genfs_io.c,v 1.13.4.2.4.2 2011/05/20 08:11:28 matt Exp */
/*
* Copyright (c) 1982, 1986, 1989, 1993
@@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: genfs_io.c,v 1.13.4.2.4.2 2011/05/20 08:11:28 matt Exp $");
+__KERNEL_RCSID(0, "genfs_io.c,v 1.13.4.2.4.2 2011/05/20 08:11:28 matt Exp");
#include <sys/param.h>
#include <sys/systm.h>
@@ -1746,9 +1746,11 @@
map = &vs->vm_map;
upm = vm_map_pmap(map);
kpm = vm_map_pmap(kernel_map);
- kva = uvm_km_alloc(kernel_map, klen, 0,
- UVM_KMF_VAONLY | UVM_KMF_WAITVA);
puva = trunc_page(uva);
+
+ kva = uvm_km_alloc(kernel_map, klen, atop(puva) & uvmexp.colormask,
+ UVM_KMF_COLORMATCH | UVM_KMF_VAONLY | UVM_KMF_WAITVA);
+
for (poff = 0; poff < klen; poff += PAGE_SIZE) {
rv = pmap_extract(upm, puva + poff, &pa);
KASSERT(rv);
Index: src/sys/sys/socketvar.h
diff -u src/sys/sys/socketvar.h:1.116.4.2 src/sys/sys/socketvar.h:1.116.4.2.4.1
--- src/sys/sys/socketvar.h:1.116.4.2 Sat Apr 4 23:36:28 2009
+++ src/sys/sys/socketvar.h Wed May 25 23:58:49 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: socketvar.h,v 1.116.4.2 2009/04/04 23:36:28 snj Exp $ */
+/* socketvar.h,v 1.116.4.2 2009/04/04 23:36:28 snj Exp */
/*-
* Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
@@ -505,7 +505,7 @@
#endif /* SOCKBUF_DEBUG */
/* sosend loan */
-vaddr_t sokvaalloc(vsize_t, struct socket *);
+vaddr_t sokvaalloc(vaddr_t, vsize_t, struct socket *);
void sokvafree(vaddr_t, vsize_t);
void soloanfree(struct mbuf *, void *, size_t, void *);
Index: src/sys/uvm/uvm_aobj.c
diff -u src/sys/uvm/uvm_aobj.c:1.104 src/sys/uvm/uvm_aobj.c:1.104.10.1
--- src/sys/uvm/uvm_aobj.c:1.104 Sat Oct 18 03:46:22 2008
+++ src/sys/uvm/uvm_aobj.c Wed May 25 23:58:49 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: uvm_aobj.c,v 1.104 2008/10/18 03:46:22 rmind Exp $ */
+/* uvm_aobj.c,v 1.104 2008/10/18 03:46:22 rmind Exp */
/*
* Copyright (c) 1998 Chuck Silvers, Charles D. Cranor and
@@ -43,7 +43,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uvm_aobj.c,v 1.104 2008/10/18 03:46:22 rmind Exp $");
+__KERNEL_RCSID(0, "uvm_aobj.c,v 1.104 2008/10/18 03:46:22 rmind Exp");
#include "opt_uvmhist.h"
@@ -976,7 +976,7 @@
if (ptmp == NULL && uao_find_swslot(&aobj->u_obj,
current_offset >> PAGE_SHIFT) == 0) {
ptmp = uvm_pagealloc(uobj, current_offset,
- NULL, UVM_PGA_ZERO);
+ NULL, UVM_FLAG_COLORMATCH|UVM_PGA_ZERO);
if (ptmp) {
/* new page */
ptmp->flags &= ~(PG_FAKE);
Index: src/sys/uvm/uvm_extern.h
diff -u src/sys/uvm/uvm_extern.h:1.148.4.2.4.1 src/sys/uvm/uvm_extern.h:1.148.4.2.4.2
--- src/sys/uvm/uvm_extern.h:1.148.4.2.4.1 Tue Jan 26 21:26:28 2010
+++ src/sys/uvm/uvm_extern.h Wed May 25 23:58:49 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: uvm_extern.h,v 1.148.4.2.4.1 2010/01/26 21:26:28 matt Exp $ */
+/* uvm_extern.h,v 1.148.4.2.4.1 2010/01/26 21:26:28 matt Exp */
/*
*
@@ -173,6 +173,7 @@
#define UVM_KMF_TRYLOCK UVM_FLAG_TRYLOCK /* try locking only */
#define UVM_KMF_NOWAIT UVM_FLAG_NOWAIT /* not allowed to sleep */
#define UVM_KMF_WAITVA UVM_FLAG_WAITVA /* sleep for va */
+#define UVM_KMF_COLORMATCH UVM_FLAG_COLORMATCH /* start at color in align */
/*
* the following defines the strategies for uvm_pagealloc_strat()
Index: src/sys/uvm/uvm_fault.c
diff -u src/sys/uvm/uvm_fault.c:1.125.6.1.4.1 src/sys/uvm/uvm_fault.c:1.125.6.1.4.2
--- src/sys/uvm/uvm_fault.c:1.125.6.1.4.1 Tue Jan 26 21:26:28 2010
+++ src/sys/uvm/uvm_fault.c Wed May 25 23:58:49 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: uvm_fault.c,v 1.125.6.1.4.1 2010/01/26 21:26:28 matt Exp $ */
+/* uvm_fault.c,v 1.125.6.1.4.1 2010/01/26 21:26:28 matt Exp */
/*
*
@@ -39,7 +39,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uvm_fault.c,v 1.125.6.1.4.1 2010/01/26 21:26:28 matt Exp $");
+__KERNEL_RCSID(0, "uvm_fault.c,v 1.125.6.1.4.1 2010/01/26 21:26:28 matt Exp");
#include "opt_uvmhist.h"
@@ -361,7 +361,7 @@
/*
* no page, we must try and bring it in.
*/
-
+ KASSERT(ufi != NULL);
pg = uvm_pagealloc(NULL, ufi->orig_rvaddr,
NULL, UVM_FLAG_COLORMATCH);
if (pg == NULL) { /* out of RAM. */
Index: src/sys/uvm/uvm_km.c
diff -u src/sys/uvm/uvm_km.c:1.101.4.2.4.3 src/sys/uvm/uvm_km.c:1.101.4.2.4.4
--- src/sys/uvm/uvm_km.c:1.101.4.2.4.3 Sat Feb 6 05:28:30 2010
+++ src/sys/uvm/uvm_km.c Wed May 25 23:58:50 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: uvm_km.c,v 1.101.4.2.4.3 2010/02/06 05:28:30 matt Exp $ */
+/* uvm_km.c,v 1.101.4.2.4.3 2010/02/06 05:28:30 matt Exp */
/*
* Copyright (c) 1997 Charles D. Cranor and Washington University.
@@ -128,7 +128,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uvm_km.c,v 1.101.4.2.4.3 2010/02/06 05:28:30 matt Exp $");
+__KERNEL_RCSID(0, "uvm_km.c,v 1.101.4.2.4.3 2010/02/06 05:28:30 matt Exp");
#include "opt_uvmhist.h"
@@ -541,6 +541,8 @@
KASSERT((flags & UVM_KMF_TYPEMASK) == UVM_KMF_WIRED ||
(flags & UVM_KMF_TYPEMASK) == UVM_KMF_PAGEABLE ||
(flags & UVM_KMF_TYPEMASK) == UVM_KMF_VAONLY);
+ KASSERT((flags & UVM_KMF_VAONLY) != 0 || (flags & UVM_KMF_COLORMATCH) == 0);
+ KASSERT((flags & UVM_KMF_COLORMATCH) == 0 || (flags & UVM_KMF_VAONLY) != 0);
/*
* setup for call
@@ -559,7 +561,7 @@
if (__predict_false(uvm_map(map, &kva, size, obj, UVM_UNKNOWN_OFFSET,
align, UVM_MAPFLAG(UVM_PROT_ALL, UVM_PROT_ALL, UVM_INH_NONE,
UVM_ADV_RANDOM,
- (flags & (UVM_KMF_TRYLOCK | UVM_KMF_NOWAIT | UVM_KMF_WAITVA))
+ (flags & (UVM_KMF_TRYLOCK | UVM_KMF_NOWAIT | UVM_KMF_WAITVA | UVM_KMF_COLORMATCH))
| UVM_FLAG_QUANTUM)) != 0)) {
UVMHIST_LOG(maphist, "<- done (no VM)",0,0,0,0);
return(0);
Index: src/sys/uvm/uvm_map.c
diff -u src/sys/uvm/uvm_map.c:1.263.4.3.4.3 src/sys/uvm/uvm_map.c:1.263.4.3.4.4
--- src/sys/uvm/uvm_map.c:1.263.4.3.4.3 Thu Aug 19 07:30:31 2010
+++ src/sys/uvm/uvm_map.c Wed May 25 23:58:50 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: uvm_map.c,v 1.263.4.3.4.3 2010/08/19 07:30:31 matt Exp $ */
+/* uvm_map.c,v 1.263.4.3.4.3 2010/08/19 07:30:31 matt Exp */
/*
* Copyright (c) 1997 Charles D. Cranor and Washington University.
@@ -71,7 +71,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uvm_map.c,v 1.263.4.3.4.3 2010/08/19 07:30:31 matt Exp $");
+__KERNEL_RCSID(0, "uvm_map.c,v 1.263.4.3.4.3 2010/08/19 07:30:31 matt Exp");
#include "opt_ddb.h"
#include "opt_uvmhist.h"
@@ -304,7 +304,7 @@
static void uvm_map_entry_unwire(struct vm_map *, struct vm_map_entry *);
static void uvm_map_reference_amap(struct vm_map_entry *, int);
static int uvm_map_space_avail(vaddr_t *, vsize_t, voff_t, vsize_t, int,
- struct vm_map_entry *);
+ int, struct vm_map_entry *);
static void uvm_map_unreference_amap(struct vm_map_entry *, int);
int _uvm_map_sanity(struct vm_map *);
@@ -1852,7 +1852,7 @@
*/
static int
uvm_map_space_avail(vaddr_t *start, vsize_t length, voff_t uoffset,
- vsize_t align, int topdown, struct vm_map_entry *entry)
+ vsize_t align, int flags, int topdown, struct vm_map_entry *entry)
{
vaddr_t end;
@@ -1865,7 +1865,27 @@
if (uoffset != UVM_UNKNOWN_OFFSET)
PMAP_PREFER(uoffset, start, length, topdown);
#endif
- if (align != 0) {
+ if ((flags & UVM_FLAG_COLORMATCH) != 0) {
+ KASSERT(align < uvmexp.ncolors);
+ if (uvmexp.ncolors > 1) {
+ const u_int colormask = uvmexp.colormask;
+ const u_int colorsize = colormask + 1;
+ vaddr_t hint = atop(*start);
+ const u_int color = hint & colormask;
+ if (color != align) {
+ hint -= color; /* adjust to color boundary */
+ KASSERT((hint & colormask) == 0);
+ if (topdown) {
+ if (align > color)
+ hint -= colorsize;
+ } else {
+ if (align < color)
+ hint += colorsize;
+ }
+ *start = ptoa(hint + align); /* adjust to color */
+ }
+ }
+ } else if (align != 0) {
if ((*start & (align - 1)) != 0) {
if (topdown)
*start &= ~(align - 1);
@@ -1921,7 +1941,8 @@
UVMHIST_LOG(maphist, "(map=0x%x, hint=0x%x, len=%d, flags=0x%x)",
map, hint, length, flags);
- KASSERT((align & (align - 1)) == 0);
+ KASSERT((flags & UVM_FLAG_COLORMATCH) != 0 || (align & (align - 1)) == 0);
+ KASSERT((flags & UVM_FLAG_COLORMATCH) == 0 || align < uvmexp.ncolors);
KASSERT((flags & UVM_FLAG_FIXED) == 0 || align == 0);
uvm_map_check(map, "map_findspace entry");
@@ -1999,7 +2020,7 @@
* See if given hint fits in this gap.
*/
switch (uvm_map_space_avail(&hint, length,
- uoffset, align, topdown, entry)) {
+ uoffset, align, flags, topdown, entry)) {
case 1:
goto found;
case -1:
@@ -2030,7 +2051,7 @@
/* Check slot before any entry */
hint = topdown ? entry->next->start - length : entry->end;
- switch (uvm_map_space_avail(&hint, length, uoffset, align,
+ switch (uvm_map_space_avail(&hint, length, uoffset, align, flags,
topdown, entry)) {
case 1:
goto found;
@@ -2099,7 +2120,7 @@
hint = tmp->end;
}
switch (uvm_map_space_avail(&hint, length, uoffset, align,
- topdown, tmp)) {
+ flags, topdown, tmp)) {
case 1:
entry = tmp;
goto found;
@@ -2121,7 +2142,7 @@
hint = prev->end;
}
switch (uvm_map_space_avail(&hint, length, uoffset, align,
- topdown, prev)) {
+ flags, topdown, prev)) {
case 1:
entry = prev;
goto found;
@@ -2162,7 +2183,7 @@
hint = tmp->end;
}
switch (uvm_map_space_avail(&hint, length, uoffset, align,
- topdown, tmp)) {
+ flags, topdown, tmp)) {
case 1:
entry = tmp;
goto found;
@@ -2188,7 +2209,7 @@
/* See if it fits. */
switch (uvm_map_space_avail(&hint, length, uoffset, align,
- topdown, entry)) {
+ flags, topdown, entry)) {
case 1:
goto found;
case -1:
@@ -4639,7 +4660,7 @@
}
error = uvm_map_prepare(map, 0, PAGE_SIZE, NULL, UVM_UNKNOWN_OFFSET,
- 0, mapflags, &args);
+ VM_PAGE_TO_COLOR(pg), mapflags | UVM_FLAG_COLORMATCH, &args);
if (error) {
uvm_pagefree(pg);
return NULL;
Index: src/sys/uvm/uvm_page.h
diff -u src/sys/uvm/uvm_page.h:1.55.14.2 src/sys/uvm/uvm_page.h:1.55.14.3
--- src/sys/uvm/uvm_page.h:1.55.14.2 Fri Apr 29 08:16:42 2011
+++ src/sys/uvm/uvm_page.h Wed May 25 23:58:50 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: uvm_page.h,v 1.55.14.2 2011/04/29 08:16:42 matt Exp $ */
+/* uvm_page.h,v 1.55.14.2 2011/04/29 08:16:42 matt Exp */
/*
* Copyright (c) 1997 Charles D. Cranor and Washington University.
@@ -307,6 +307,7 @@
(((unsigned long)obj+(unsigned long)atop(off)) & uvm.page_hashmask)
#define VM_PAGE_TO_PHYS(entry) ((entry)->phys_addr)
+#define VM_PAGE_TO_COLOR(entry) (atop((entry)->phys_addr) & uvmexp.colormask)
#ifdef __HAVE_VM_PAGE_MD
#define VM_PAGE_TO_MD(pg) (&(pg)->mdpage)
Index: src/sys/uvm/uvm_pager.c
diff -u src/sys/uvm/uvm_pager.c:1.92 src/sys/uvm/uvm_pager.c:1.92.18.1
--- src/sys/uvm/uvm_pager.c:1.92 Thu Apr 17 05:39:41 2008
+++ src/sys/uvm/uvm_pager.c Wed May 25 23:58:50 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: uvm_pager.c,v 1.92 2008/04/17 05:39:41 simonb Exp $ */
+/* uvm_pager.c,v 1.92 2008/04/17 05:39:41 simonb Exp */
/*
*
@@ -39,7 +39,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uvm_pager.c,v 1.92 2008/04/17 05:39:41 simonb Exp $");
+__KERNEL_RCSID(0, "uvm_pager.c,v 1.92 2008/04/17 05:39:41 simonb Exp");
#include "opt_uvmhist.h"
#include "opt_readahead.h"
@@ -112,7 +112,8 @@
false, NULL);
mutex_init(&pager_map_wanted_lock, MUTEX_DEFAULT, IPL_NONE);
pager_map_wanted = false;
- emergva = uvm_km_alloc(kernel_map, round_page(MAXPHYS), 0,
+ emergva = uvm_km_alloc(kernel_map,
+ round_page(MAXPHYS) + ptoa(uvmexp.ncolors), 0,
UVM_KMF_VAONLY);
#if defined(DEBUG)
if (emergva == 0)
@@ -150,10 +151,12 @@
vaddr_t cva;
struct vm_page *pp;
vm_prot_t prot;
- const bool pdaemon = curlwp == uvm.pagedaemon_lwp;
+ const bool pdaemon = (curlwp == uvm.pagedaemon_lwp);
+ const u_int first_color = VM_PAGE_TO_COLOR(*pps);
UVMHIST_FUNC("uvm_pagermapin"); UVMHIST_CALLED(maphist);
- UVMHIST_LOG(maphist,"(pps=0x%x, npages=%d)", pps, npages,0,0);
+ UVMHIST_LOG(maphist,"(pps=0x%x, npages=%d, first_color=%u)",
+ pps, npages, first_color, 0);
/*
* compute protection. outgoing I/O only needs read
@@ -165,11 +168,12 @@
prot |= VM_PROT_WRITE;
ReStart:
- size = npages << PAGE_SHIFT;
+ size = ptoa(npages);
kva = 0; /* let system choose VA */
- if (uvm_map(pager_map, &kva, size, NULL, UVM_UNKNOWN_OFFSET, 0,
- UVM_FLAG_NOMERGE | (pdaemon ? UVM_FLAG_NOWAIT : 0)) != 0) {
+ if (uvm_map(pager_map, &kva, size, NULL, UVM_UNKNOWN_OFFSET,
+ first_color, UVM_FLAG_COLORMATCH | UVM_FLAG_NOMERGE
+ | (pdaemon ? UVM_FLAG_NOWAIT : 0)) != 0) {
if (pdaemon) {
mutex_enter(&pager_map_wanted_lock);
if (emerginuse) {
@@ -180,7 +184,7 @@
}
emerginuse = true;
mutex_exit(&pager_map_wanted_lock);
- kva = emergva;
+ kva = emergva + ptoa(first_color);
/* The shift implicitly truncates to PAGE_SIZE */
KASSERT(npages <= (MAXPHYS >> PAGE_SHIFT));
goto enter;
@@ -199,9 +203,10 @@
enter:
/* got it */
- for (cva = kva ; size != 0 ; size -= PAGE_SIZE, cva += PAGE_SIZE) {
+ for (cva = kva; npages != 0; npages--, cva += PAGE_SIZE) {
pp = *pps++;
KASSERT(pp);
+ KASSERT(((VM_PAGE_TO_PHYS(pp) ^ cva) & uvmexp.colormask) == 0);
KASSERT(pp->flags & PG_BUSY);
pmap_kenter_pa(cva, VM_PAGE_TO_PHYS(pp), prot);
}
@@ -221,7 +226,7 @@
void
uvm_pagermapout(vaddr_t kva, int npages)
{
- vsize_t size = npages << PAGE_SHIFT;
+ vsize_t size = ptoa(npages);
struct vm_map_entry *entries;
UVMHIST_FUNC("uvm_pagermapout"); UVMHIST_CALLED(maphist);
@@ -231,8 +236,9 @@
* duplicate uvm_unmap, but add in pager_map_wanted handling.
*/
- pmap_kremove(kva, npages << PAGE_SHIFT);
- if (kva == emergva) {
+ pmap_kremove(kva, size);
+
+ if ((kva & ~ptoa(uvmexp.colormask)) == emergva) {
mutex_enter(&pager_map_wanted_lock);
emerginuse = false;
wakeup(&emergva);
Index: src/sys/uvm/uvm_pglist.c
diff -u src/sys/uvm/uvm_pglist.c:1.42.16.6 src/sys/uvm/uvm_pglist.c:1.42.16.7
--- src/sys/uvm/uvm_pglist.c:1.42.16.6 Tue Jun 1 19:04:02 2010
+++ src/sys/uvm/uvm_pglist.c Wed May 25 23:58:50 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: uvm_pglist.c,v 1.42.16.6 2010/06/01 19:04:02 matt Exp $ */
+/* uvm_pglist.c,v 1.42.16.6 2010/06/01 19:04:02 matt Exp */
/*-
* Copyright (c) 1997 The NetBSD Foundation, Inc.
@@ -35,7 +35,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uvm_pglist.c,v 1.42.16.6 2010/06/01 19:04:02 matt Exp $");
+__KERNEL_RCSID(0, "uvm_pglist.c,v 1.42.16.6 2010/06/01 19:04:02 matt Exp");
#include <sys/param.h>
#include <sys/systm.h>
@@ -353,9 +353,10 @@
uvm_pglistalloc_s_ps(struct vm_physseg *ps, int num, paddr_t low, paddr_t high,
struct pglist *rlist)
{
- int todo, limit, try;
+ int todo, limit, try, color;
struct vm_page *pg;
- bool second_pass;
+ bool second_pass, colorless;
+ const int colormask = uvmexp.colormask;
#ifdef DEBUG
int cidx = 0; /* XXX: GCC */
#endif
@@ -366,6 +367,20 @@
KASSERT(mutex_owned(&uvm_fpageqlock));
+ /*
+ * If the pageq (rlist) is empty, then no pages have been allocated
+ * and we can start with any color. If it wasn't empty, then the
+ * starting color is the last page's next color.
+ */
+ colorless = TAILQ_EMPTY(rlist);
+ color = (ps->avail_start + ps->start_hint) & colormask;
+#ifdef DIAGNOSTIC
+ if (!colorless) {
+ pg = TAILQ_LAST(rlist, pglist);
+ KASSERT(color == ((VM_PAGE_TO_COLOR(pg) + 1) & colormask));
+ }
+#endif
+
low = atop(low);
high = atop(high);
todo = num;
@@ -379,7 +394,7 @@
if (ps->start_hint == 0 || second_pass)
break;
second_pass = true;
- try = max(low, ps->avail_start);
+ try = max(low, ps->avail_start) - 1;
limit = min(high, ps->avail_start + ps->start_hint);
pg = &ps->pgs[try - ps->start];
continue;
@@ -390,13 +405,42 @@
if (cidx != (try - ps->start))
panic("pgalloc simple: botch2");
#endif
- if (VM_PAGE_IS_FREE(pg) == 0)
+ /*
+ * If this page isn't free, then we need to skip a colors worth
+ * of pages to get a matching color. Note that colormask is 1
+ * less than what we need since the loop will also increment
+ * try and pgs.
+ */
+ if (VM_PAGE_IS_FREE(pg) == 0) {
+ try += colormask;
+ pg += colormask;
continue;
+ }
+
+ /*
+ * If this page doesn't have the right color, figure out how
+ * many pages we need to skip until we get to the right color.
+ * Note that skip is 1 less that what we need since the loop
+ * will also increment try and pgs.
+ */
+ if (!colorless && (try & colormask) != color) {
+ const int skip = (color - (try + 1)) & colormask;
+ try += skip;
+ pg += skip;
+ continue;
+ }
uvm_pglist_add(pg, rlist);
if (--todo == 0) {
break;
}
+
+ /*
+ * Advance the color (use try instead of color in case we
+ * haven't set an initial color).
+ */
+ color = (try + 1) & colormask;
+ colorless = false;
}
/*
Index: src/sys/uvm/uvm_vnode.c
diff -u src/sys/uvm/uvm_vnode.c:1.90 src/sys/uvm/uvm_vnode.c:1.90.28.1
--- src/sys/uvm/uvm_vnode.c:1.90 Wed Jan 2 11:49:21 2008
+++ src/sys/uvm/uvm_vnode.c Wed May 25 23:58:50 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: uvm_vnode.c,v 1.90 2008/01/02 11:49:21 ad Exp $ */
+/* uvm_vnode.c,v 1.90 2008/01/02 11:49:21 ad Exp */
/*
* Copyright (c) 1997 Charles D. Cranor and Washington University.
@@ -50,7 +50,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uvm_vnode.c,v 1.90 2008/01/02 11:49:21 ad Exp $");
+__KERNEL_RCSID(0, "uvm_vnode.c,v 1.90 2008/01/02 11:49:21 ad Exp");
#include "fs_nfs.h"
#include "opt_uvmhist.h"
@@ -257,7 +257,8 @@
UVMHIST_LOG(ubchist, "noalloc", 0,0,0,0);
return 0;
}
- pg = uvm_pagealloc(uobj, offset, NULL, 0);
+ pg = uvm_pagealloc(uobj, offset, NULL,
+ UVM_FLAG_COLORMATCH);
if (pg == NULL) {
if (flags & UFP_NOWAIT) {
UVMHIST_LOG(ubchist, "nowait",0,0,0,0);