diff options
author | Bob Beck <beck@cvs.openbsd.org> | 2011-04-02 16:47:18 +0000 |
---|---|---|
committer | Bob Beck <beck@cvs.openbsd.org> | 2011-04-02 16:47:18 +0000 |
commit | 11ae302ebcf8bbe27cb1c13a64dce31c551cdac8 (patch) | |
tree | ff5ae54716a7cff0ff2b2e11852beffcff447d67 /sys | |
parent | f3acb273af8efc67104501a764c2ac28a24d7ec3 (diff) |
Constrain the buffer cache to use only the dma reachable region of memory.
With this change bufcachepercent will be the percentage of dma reachable
memory that the buffer cache will attempt to use.
ok deraadt@ thib@ oga@
Diffstat (limited to 'sys')
-rw-r--r-- | sys/kern/kern_sysctl.c | 6 | ||||
-rw-r--r-- | sys/kern/vfs_bio.c | 11 | ||||
-rw-r--r-- | sys/kern/vfs_biomem.c | 24 | ||||
-rw-r--r-- | sys/uvm/uvm_extern.h | 4 | ||||
-rw-r--r-- | sys/uvm/uvm_page.c | 28 |
5 files changed, 46 insertions, 27 deletions
diff --git a/sys/kern/kern_sysctl.c b/sys/kern/kern_sysctl.c index 8e862ed8b6e..a2536b7a297 100644 --- a/sys/kern/kern_sysctl.c +++ b/sys/kern/kern_sysctl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_sysctl.c,v 1.198 2011/03/12 04:54:28 guenther Exp $ */ +/* $OpenBSD: kern_sysctl.c,v 1.199 2011/04/02 16:47:17 beck Exp $ */ /* $NetBSD: kern_sysctl.c,v 1.17 1996/05/20 17:49:05 mrg Exp $ */ /*- @@ -564,6 +564,7 @@ kern_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, return (sysctl_int(oldp, oldlenp, newp, newlen, &rthreads_enabled)); case KERN_CACHEPCT: { + u_int64_t dmapages; int opct, pgs; opct = bufcachepercent; error = sysctl_int(oldp, oldlenp, newp, newlen, @@ -574,8 +575,9 @@ kern_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, bufcachepercent = opct; return (EINVAL); } + dmapages = uvm_pagecount(&dma_constraint); if (bufcachepercent != opct) { - pgs = bufcachepercent * physmem / 100; + pgs = bufcachepercent * dmapages / 100; bufadjust(pgs); /* adjust bufpages */ bufhighpages = bufpages; /* set high water mark */ } diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c index a285a3e6dd0..c48624f9b3a 100644 --- a/sys/kern/vfs_bio.c +++ b/sys/kern/vfs_bio.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vfs_bio.c,v 1.127 2010/11/13 17:45:44 deraadt Exp $ */ +/* $OpenBSD: vfs_bio.c,v 1.128 2011/04/02 16:47:17 beck Exp $ */ /* $NetBSD: vfs_bio.c,v 1.44 1996/06/11 11:15:36 pk Exp $ */ /* @@ -191,19 +191,22 @@ buf_put(struct buf *bp) void bufinit(void) { + u_int64_t dmapages; struct bqueues *dp; /* XXX - for now */ bufhighpages = buflowpages = bufpages = bufcachepercent = bufkvm = 0; + dmapages = uvm_pagecount(&dma_constraint); + /* * If MD code doesn't say otherwise, use 10% of kvm for mappings and - * 10% physmem for pages. + * 10% of dmaable pages for cache pages. */ if (bufcachepercent == 0) bufcachepercent = 10; if (bufpages == 0) - bufpages = physmem * bufcachepercent / 100; + bufpages = dmapages * bufcachepercent / 100; bufhighpages = bufpages; @@ -212,7 +215,7 @@ bufinit(void) * we will not allow uvm to steal back more than this number of * pages */ - buflowpages = physmem * 10 / 100; + buflowpages = dmapages * 10 / 100; /* * set bufbackpages to 100 pages, or 10 percent of the low water mark diff --git a/sys/kern/vfs_biomem.c b/sys/kern/vfs_biomem.c index c850b0dba57..4d55308cbd1 100644 --- a/sys/kern/vfs_biomem.c +++ b/sys/kern/vfs_biomem.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vfs_biomem.c,v 1.14 2010/04/30 21:56:39 oga Exp $ */ +/* $OpenBSD: vfs_biomem.c,v 1.15 2011/04/02 16:47:17 beck Exp $ */ /* * Copyright (c) 2007 Artur Grabowski <art@openbsd.org> * @@ -259,11 +259,11 @@ buf_unmap(struct buf *bp) return (va); } +/* Always allocates in dma-reachable memory */ void buf_alloc_pages(struct buf *bp, vsize_t size) { - struct vm_page *pg; - voff_t offs, i; + voff_t offs; int s; KASSERT(size == round_page(size)); @@ -277,22 +277,8 @@ buf_alloc_pages(struct buf *bp, vsize_t size) KASSERT(buf_page_offset > 0); - for (i = 0; i < atop(size); i++) { -#if defined(DEBUG) || 1 - if ((pg = uvm_pagelookup(buf_object, offs + ptoa(i)))) - panic("buf_alloc_pages: overlap buf: %p page: %p", - bp, pg); -#endif - - while ((pg = uvm_pagealloc(buf_object, offs + ptoa(i), - NULL, 0)) == NULL) { - uvm_wait("buf_alloc_pages"); - } - pg->wire_count = 1; - atomic_clearbits_int(&pg->pg_flags, PG_BUSY); - bcstats.numbufpages++; - } - + uvm_pagealloc_multi(buf_object, offs, size, UVM_PLA_WAITOK); + bcstats.numbufpages += atop(size); bp->b_pobj = buf_object; bp->b_poffs = offs; bp->b_bufsize = size; diff --git a/sys/uvm/uvm_extern.h b/sys/uvm/uvm_extern.h index 66f4ed1d22f..a6448d99b20 100644 --- a/sys/uvm/uvm_extern.h +++ b/sys/uvm/uvm_extern.h @@ -1,4 +1,4 @@ -/* $OpenBSD: uvm_extern.h,v 1.89 2010/07/02 01:25:06 art Exp $ */ +/* $OpenBSD: uvm_extern.h,v 1.90 2011/04/02 16:47:17 beck Exp $ */ /* $NetBSD: uvm_extern.h,v 1.57 2001/03/09 01:02:12 chs Exp $ */ /* @@ -583,6 +583,8 @@ struct vm_page *uvm_pagealloc(struct uvm_object *, voff_t, struct vm_anon *, int); vaddr_t uvm_pagealloc_contig(vaddr_t, vaddr_t, vaddr_t, vaddr_t); +void uvm_pagealloc_multi(struct uvm_object *, voff_t, + vsize_t, int); void uvm_pagerealloc(struct vm_page *, struct uvm_object *, voff_t); /* Actually, uvm_page_physload takes PF#s which need their own type */ diff --git a/sys/uvm/uvm_page.c b/sys/uvm/uvm_page.c index 82951d1c99f..a431450748a 100644 --- a/sys/uvm/uvm_page.c +++ b/sys/uvm/uvm_page.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uvm_page.c,v 1.103 2011/04/02 12:38:37 ariane Exp $ */ +/* $OpenBSD: uvm_page.c,v 1.104 2011/04/02 16:47:17 beck Exp $ */ /* $NetBSD: uvm_page.c,v 1.44 2000/11/27 08:40:04 chs Exp $ */ /* @@ -804,6 +804,32 @@ uvm_pagealloc_pg(struct vm_page *pg, struct uvm_object *obj, voff_t off, } /* + * interface used by the buffer cache to allocate a buffer at a time. + * The pages are allocated wired in DMA accessible memory + */ +void +uvm_pagealloc_multi(struct uvm_object *obj, voff_t off, vsize_t size, int flags) +{ + struct pglist plist; + struct vm_page *pg; + int i; + + + TAILQ_INIT(&plist); + (void) uvm_pglistalloc(size, dma_constraint.ucr_low, + dma_constraint.ucr_high, 0, 0, &plist, atop(round_page(size)), + UVM_PLA_WAITOK); + i = 0; + while ((pg = TAILQ_FIRST(&plist)) != NULL) { + pg->wire_count = 1; + atomic_setbits_int(&pg->pg_flags, PG_CLEAN | PG_FAKE); + KASSERT((pg->pg_flags & PG_DEV) == 0); + TAILQ_REMOVE(&plist, pg, pageq); + uvm_pagealloc_pg(pg, obj, off + ptoa(i++), NULL); + } +} + +/* * uvm_pagealloc_strat: allocate vm_page from a particular free list. * * => return null if no pages free |