summaryrefslogtreecommitdiffstats
path: root/sys/kern/vfs_bio.c
diff options
context:
space:
mode:
authoralc <alc@FreeBSD.org>2010-06-30 04:52:42 +0000
committeralc <alc@FreeBSD.org>2010-06-30 04:52:42 +0000
commitdf23299909b99ddf451f2e9a56844ba8d99ed2d5 (patch)
tree63e55f60401f3f29fb79ab6698fefd808b271f41 /sys/kern/vfs_bio.c
parentf2891c465ef29098b2cd144a91ea21ddb7a58b96 (diff)
downloadFreeBSD-src-df23299909b99ddf451f2e9a56844ba8d99ed2d5.zip
FreeBSD-src-df23299909b99ddf451f2e9a56844ba8d99ed2d5.tar.gz
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 after: 3 weeks
Diffstat (limited to 'sys/kern/vfs_bio.c')
-rw-r--r--sys/kern/vfs_bio.c10
1 files changed, 6 insertions, 4 deletions
diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c
index df8bf66..95f8929 100644
--- a/sys/kern/vfs_bio.c
+++ b/sys/kern/vfs_bio.c
@@ -3336,7 +3336,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;
@@ -3374,6 +3374,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;
@@ -3387,13 +3388,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) {
@@ -3447,6 +3446,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);
}
/*
OpenPOWER on IntegriCloud