diff options
author | alc <alc@FreeBSD.org> | 2010-05-03 16:41:11 +0000 |
---|---|---|
committer | alc <alc@FreeBSD.org> | 2010-05-03 16:41:11 +0000 |
commit | 1923b6ded3da335e5752c75a0ad1b1219e63521b (patch) | |
tree | 2ce56dcf8d985c7cfece005a9db1b3f13ff3a59a /sys/kern/vfs_bio.c | |
parent | e50916c7a291f469ef1a4e154080873a81efcbc0 (diff) | |
download | FreeBSD-src-1923b6ded3da335e5752c75a0ad1b1219e63521b.zip FreeBSD-src-1923b6ded3da335e5752c75a0ad1b1219e63521b.tar.gz |
Acquire the page lock around vm_page_unwire() and vm_page_wire().
Reviewed by: kib
Diffstat (limited to 'sys/kern/vfs_bio.c')
-rw-r--r-- | sys/kern/vfs_bio.c | 13 |
1 files changed, 9 insertions, 4 deletions
diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c index 1048998..5db2d9e 100644 --- a/sys/kern/vfs_bio.c +++ b/sys/kern/vfs_bio.c @@ -2942,7 +2942,6 @@ allocbuf(struct buf *bp, int size) vm_page_t m; VM_OBJECT_LOCK(bp->b_bufobj->bo_object); - vm_page_lock_queues(); for (i = desiredpages; i < bp->b_npages; i++) { /* * the page is not freed here -- it @@ -2952,13 +2951,17 @@ allocbuf(struct buf *bp, int size) m = bp->b_pages[i]; KASSERT(m != bogus_page, ("allocbuf: bogus page found")); - while (vm_page_sleep_if_busy(m, TRUE, "biodep")) - vm_page_lock_queues(); + while (vm_page_sleep_if_busy(m, TRUE, + "biodep")) + continue; bp->b_pages[i] = NULL; + vm_page_lock(m); + vm_page_lock_queues(); vm_page_unwire(m, 0); + vm_page_unlock_queues(); + vm_page_unlock(m); } - vm_page_unlock_queues(); 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)); @@ -3039,9 +3042,11 @@ allocbuf(struct buf *bp, int size) /* * We have a good page. */ + vm_page_lock(m); vm_page_lock_queues(); vm_page_wire(m); vm_page_unlock_queues(); + vm_page_unlock(m); bp->b_pages[bp->b_npages] = m; ++bp->b_npages; } |