svn commit: r213890 - stable/8/sys/kern
Alan Cox
alc at FreeBSD.org
Fri Oct 15 05:42:36 UTC 2010
Author: alc
Date: Fri Oct 15 05:42:35 2010
New Revision: 213890
URL: http://svn.freebsd.org/changeset/base/213890
Log:
MFC r209605
Improve bufdone_finish()'s handling of the bogus page. Specifically, if
one or more mappings to the bogus page must be replaced, call pmap_qenter()
just once. Previously, pmap_qenter() was called for each mapping to the
bogus page.
MFC r209902
Change the implementation of vm_hold_free_pages() so that it performs at
most one call to pmap_qremove(), and thus one TLB shootdown, instead of one
call and TLB shootdown per page.
Simplify the interface to vm_hold_free_pages().
Modified:
stable/8/sys/kern/vfs_bio.c
Directory Properties:
stable/8/sys/ (props changed)
stable/8/sys/amd64/include/xen/ (props changed)
stable/8/sys/cddl/contrib/opensolaris/ (props changed)
stable/8/sys/contrib/dev/acpica/ (props changed)
stable/8/sys/contrib/pf/ (props changed)
stable/8/sys/dev/xen/xenpci/ (props changed)
Modified: stable/8/sys/kern/vfs_bio.c
==============================================================================
--- stable/8/sys/kern/vfs_bio.c Fri Oct 15 05:17:48 2010 (r213889)
+++ stable/8/sys/kern/vfs_bio.c Fri Oct 15 05:42:35 2010 (r213890)
@@ -95,8 +95,7 @@ struct buf *buf; /* buffer header pool
static struct proc *bufdaemonproc;
static int inmem(struct vnode *vp, daddr_t blkno);
-static void vm_hold_free_pages(struct buf *bp, vm_offset_t from,
- vm_offset_t to);
+static void vm_hold_free_pages(struct buf *bp, int newbsize);
static void vm_hold_load_pages(struct buf *bp, vm_offset_t from,
vm_offset_t to);
static void vfs_page_set_valid(struct buf *bp, vm_ooffset_t off, vm_page_t m);
@@ -2919,10 +2918,7 @@ allocbuf(struct buf *bp, int size)
}
return 1;
}
- vm_hold_free_pages(
- bp,
- (vm_offset_t) bp->b_data + newbsize,
- (vm_offset_t) bp->b_data + bp->b_bufsize);
+ vm_hold_free_pages(bp, newbsize);
} else if (newbsize > bp->b_bufsize) {
/*
* We only use malloced memory on the first allocation.
@@ -3358,7 +3354,7 @@ bufdone_finish(struct buf *bp)
vm_ooffset_t foff;
vm_page_t m;
vm_object_t obj;
- int iosize;
+ int bogus, iosize;
struct vnode *vp = bp->b_vp;
obj = bp->b_bufobj->bo_object;
@@ -3396,6 +3392,7 @@ bufdone_finish(struct buf *bp)
!(bp->b_ioflags & BIO_ERROR)) {
bp->b_flags |= B_CACHE;
}
+ bogus = 0;
for (i = 0; i < bp->b_npages; i++) {
int bogusflag = 0;
int resid;
@@ -3409,13 +3406,11 @@ bufdone_finish(struct buf *bp)
*/
m = bp->b_pages[i];
if (m == bogus_page) {
- bogusflag = 1;
+ bogus = bogusflag = 1;
m = vm_page_lookup(obj, OFF_TO_IDX(foff));
if (m == NULL)
panic("biodone: page disappeared!");
bp->b_pages[i] = m;
- pmap_qenter(trunc_page((vm_offset_t)bp->b_data),
- bp->b_pages, bp->b_npages);
}
#if defined(VFS_BIO_DEBUG)
if (OFF_TO_IDX(foff) != m->pindex) {
@@ -3469,6 +3464,9 @@ bufdone_finish(struct buf *bp)
}
vm_object_pip_wakeupn(obj, 0);
VM_OBJECT_UNLOCK(obj);
+ if (bogus)
+ pmap_qenter(trunc_page((vm_offset_t)bp->b_data),
+ bp->b_pages, bp->b_npages);
}
/*
@@ -3831,31 +3829,25 @@ tryagain:
/* Return pages associated with this buf to the vm system */
static void
-vm_hold_free_pages(struct buf *bp, vm_offset_t from, vm_offset_t to)
+vm_hold_free_pages(struct buf *bp, int newbsize)
{
- vm_offset_t pg;
+ vm_offset_t from;
vm_page_t p;
int index, newnpages;
- from = round_page(from);
- to = round_page(to);
- newnpages = index = (from - trunc_page((vm_offset_t)bp->b_data)) >> PAGE_SHIFT;
-
- for (pg = from; pg < to; pg += PAGE_SIZE, index++) {
+ from = round_page((vm_offset_t)bp->b_data + newbsize);
+ newnpages = (from - trunc_page((vm_offset_t)bp->b_data)) >> PAGE_SHIFT;
+ if (bp->b_npages > newnpages)
+ pmap_qremove(from, bp->b_npages - newnpages);
+ for (index = newnpages; index < bp->b_npages; index++) {
p = bp->b_pages[index];
- if (p && (index < bp->b_npages)) {
- if (p->busy) {
- printf(
- "vm_hold_free_pages: blkno: %jd, lblkno: %jd\n",
- (intmax_t)bp->b_blkno,
- (intmax_t)bp->b_lblkno);
- }
- bp->b_pages[index] = NULL;
- pmap_qremove(pg, 1);
- p->wire_count--;
- vm_page_free(p);
- atomic_subtract_int(&cnt.v_wire_count, 1);
- }
+ bp->b_pages[index] = NULL;
+ if (p->busy != 0)
+ printf("vm_hold_free_pages: blkno: %jd, lblkno: %jd\n",
+ (intmax_t)bp->b_blkno, (intmax_t)bp->b_lblkno);
+ p->wire_count--;
+ vm_page_free(p);
+ atomic_subtract_int(&cnt.v_wire_count, 1);
}
bp->b_npages = newnpages;
}
More information about the svn-src-stable
mailing list