diff options
author | alc <alc@FreeBSD.org> | 2010-07-11 20:11:44 +0000 |
---|---|---|
committer | alc <alc@FreeBSD.org> | 2010-07-11 20:11:44 +0000 |
commit | db4ca9f5c252512108ab59f6dc85eaf71ab9a13b (patch) | |
tree | 5d8a191572fded2912a593b73cf9fc7d11087769 /sys/kern | |
parent | 5036d2a3734e67ef4d5575aaa5a7cc6f196cfe45 (diff) | |
download | FreeBSD-src-db4ca9f5c252512108ab59f6dc85eaf71ab9a13b.zip FreeBSD-src-db4ca9f5c252512108ab59f6dc85eaf71ab9a13b.tar.gz |
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().
MFC after: 3 weeks
Diffstat (limited to 'sys/kern')
-rw-r--r-- | sys/kern/vfs_bio.c | 42 |
1 files changed, 16 insertions, 26 deletions
diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c index 9d2beba..b1b760a 100644 --- a/sys/kern/vfs_bio.c +++ b/sys/kern/vfs_bio.c @@ -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); @@ -2888,10 +2887,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. @@ -3766,31 +3762,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; } |