diff options
author | alc <alc@FreeBSD.org> | 2013-06-02 16:18:03 +0000 |
---|---|---|
committer | alc <alc@FreeBSD.org> | 2013-06-02 16:18:03 +0000 |
commit | 3744954e30d6d19466b8d0368905fd160e5573c7 (patch) | |
tree | f97b7c69a47b048fcd304c0b4829d4c8a8feecbe /sys/kern/vfs_bio.c | |
parent | 174cc36edbb7bead76d6725363366d32d54fcb98 (diff) | |
download | FreeBSD-src-3744954e30d6d19466b8d0368905fd160e5573c7.zip FreeBSD-src-3744954e30d6d19466b8d0368905fd160e5573c7.tar.gz |
Reduce the scope of the VM object locking in brelse(). In my tests, this
change reduced the total number of VM object lock acquisitions by brelse()
by 74%.
Sponsored by: EMC / Isilon Storage Division
Diffstat (limited to 'sys/kern/vfs_bio.c')
-rw-r--r-- | sys/kern/vfs_bio.c | 6 |
1 files changed, 4 insertions, 2 deletions
diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c index 7bd8d7e..ed51997 100644 --- a/sys/kern/vfs_bio.c +++ b/sys/kern/vfs_bio.c @@ -1522,7 +1522,6 @@ brelse(struct buf *bp) */ resid = bp->b_bufsize; foff = bp->b_offset; - VM_OBJECT_WLOCK(obj); for (i = 0; i < bp->b_npages; i++) { int had_bogus = 0; @@ -1536,6 +1535,7 @@ brelse(struct buf *bp) poff = OFF_TO_IDX(bp->b_offset); had_bogus = 1; + VM_OBJECT_RLOCK(obj); for (j = i; j < bp->b_npages; j++) { vm_page_t mtmp; mtmp = bp->b_pages[j]; @@ -1547,6 +1547,7 @@ brelse(struct buf *bp) bp->b_pages[j] = mtmp; } } + VM_OBJECT_RUNLOCK(obj); if ((bp->b_flags & (B_INVAL | B_UNMAPPED)) == 0) { BUF_CHECK_MAPPED(bp); @@ -1564,14 +1565,15 @@ brelse(struct buf *bp) (PAGE_SIZE - poffset) : resid; KASSERT(presid >= 0, ("brelse: extra page")); + VM_OBJECT_WLOCK(obj); vm_page_set_invalid(m, poffset, presid); + VM_OBJECT_WUNLOCK(obj); if (had_bogus) printf("avoided corruption bug in bogus_page/brelse code\n"); } resid -= PAGE_SIZE - (foff & PAGE_MASK); foff = (foff + PAGE_SIZE) & ~(off_t)PAGE_MASK; } - VM_OBJECT_WUNLOCK(obj); if (bp->b_flags & (B_INVAL | B_RELBUF)) vfs_vmio_release(bp); |