summaryrefslogtreecommitdiffstats
path: root/sys/kern/vfs_bio.c
diff options
context:
space:
mode:
authormarius <marius@FreeBSD.org>2011-07-05 18:40:37 +0000
committermarius <marius@FreeBSD.org>2011-07-05 18:40:37 +0000
commit97f9011cd81d27c563028b9f2fe7df9169adde14 (patch)
tree8f217ab440eff877ad6e011fc9f833215dec59bd /sys/kern/vfs_bio.c
parentf71b110a36640f214204387737c5964c19a4aeee (diff)
downloadFreeBSD-src-97f9011cd81d27c563028b9f2fe7df9169adde14.zip
FreeBSD-src-97f9011cd81d27c563028b9f2fe7df9169adde14.tar.gz
Call pmap_qremove() before freeing or unwiring the pages, otherwise
there's a window during which a page can be re-used before its previous mapping is removed. Reviewed by: alc MFC after: 1 week
Diffstat (limited to 'sys/kern/vfs_bio.c')
-rw-r--r--sys/kern/vfs_bio.c8
1 files changed, 5 insertions, 3 deletions
diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c
index 2743089..a6ad81e 100644
--- a/sys/kern/vfs_bio.c
+++ b/sys/kern/vfs_bio.c
@@ -1625,6 +1625,7 @@ vfs_vmio_release(struct buf *bp)
int i;
vm_page_t m;
+ pmap_qremove(trunc_page((vm_offset_t)bp->b_data), bp->b_npages);
VM_OBJECT_LOCK(bp->b_bufobj->bo_object);
for (i = 0; i < bp->b_npages; i++) {
m = bp->b_pages[i];
@@ -1658,7 +1659,6 @@ vfs_vmio_release(struct buf *bp)
vm_page_unlock(m);
}
VM_OBJECT_UNLOCK(bp->b_bufobj->bo_object);
- pmap_qremove(trunc_page((vm_offset_t) bp->b_data), bp->b_npages);
if (bp->b_bufsize) {
bufspacewakeup();
@@ -3012,6 +3012,10 @@ allocbuf(struct buf *bp, int size)
if (desiredpages < bp->b_npages) {
vm_page_t m;
+ pmap_qremove((vm_offset_t)trunc_page(
+ (vm_offset_t)bp->b_data) +
+ (desiredpages << PAGE_SHIFT),
+ (bp->b_npages - desiredpages));
VM_OBJECT_LOCK(bp->b_bufobj->bo_object);
for (i = desiredpages; i < bp->b_npages; i++) {
/*
@@ -3032,8 +3036,6 @@ allocbuf(struct buf *bp, int size)
vm_page_unlock(m);
}
VM_OBJECT_UNLOCK(bp->b_bufobj->bo_object);
- pmap_qremove((vm_offset_t) trunc_page((vm_offset_t)bp->b_data) +
- (desiredpages << PAGE_SHIFT), (bp->b_npages - desiredpages));
bp->b_npages = desiredpages;
}
} else if (size > bp->b_bcount) {
OpenPOWER on IntegriCloud