diff options
author | kib <kib@FreeBSD.org> | 2010-07-05 21:13:32 +0000 |
---|---|---|
committer | kib <kib@FreeBSD.org> | 2010-07-05 21:13:32 +0000 |
commit | 15a394fbbad37497967f317055562bc99c9e78a3 (patch) | |
tree | 3e3d325673e269e1bed29f2e51cf834666ce009b /sys/kern | |
parent | 3b22f10bbd3187c095080cca20c4a8c47a3973b0 (diff) | |
download | FreeBSD-src-15a394fbbad37497967f317055562bc99c9e78a3.zip FreeBSD-src-15a394fbbad37497967f317055562bc99c9e78a3.tar.gz |
Add the ability for the allocflag argument of the vm_page_grab() to
specify the increment of vm_pageout_deficit when sleeping due to page
shortage. Then, in allocbuf(), the code to allocate pages when extending
vmio buffer can be replaced by a call to vm_page_grab().
Suggested and reviewed by: alc
MFC after: 2 weeks
Diffstat (limited to 'sys/kern')
-rw-r--r-- | sys/kern/vfs_bio.c | 61 |
1 files changed, 11 insertions, 50 deletions
diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c index 95f8929..762b253 100644 --- a/sys/kern/vfs_bio.c +++ b/sys/kern/vfs_bio.c @@ -3013,63 +3013,24 @@ allocbuf(struct buf *bp, int size) VM_OBJECT_LOCK(obj); while (bp->b_npages < desiredpages) { vm_page_t m; - vm_pindex_t pi; - - pi = OFF_TO_IDX(bp->b_offset) + bp->b_npages; - if ((m = vm_page_lookup(obj, pi)) == NULL) { - /* - * note: must allocate system pages - * since blocking here could intefere - * with paging I/O, no matter which - * process we are. - */ - m = vm_page_alloc(obj, pi, - VM_ALLOC_NOBUSY | VM_ALLOC_SYSTEM | - VM_ALLOC_WIRED); - if (m == NULL) { - atomic_add_int(&vm_pageout_deficit, - desiredpages - bp->b_npages); - VM_OBJECT_UNLOCK(obj); - VM_WAIT; - VM_OBJECT_LOCK(obj); - } else { - if (m->valid == 0) - bp->b_flags &= ~B_CACHE; - bp->b_pages[bp->b_npages] = m; - ++bp->b_npages; - } - continue; - } /* - * We found a page. If we have to sleep on it, - * retry because it might have gotten freed out - * from under us. + * We must allocate system pages since blocking + * here could intefere with paging I/O, no + * matter which process we are. * * We can only test VPO_BUSY here. Blocking on * m->busy might lead to a deadlock: - * * vm_fault->getpages->cluster_read->allocbuf - * - */ - if ((m->oflags & VPO_BUSY) != 0) { - /* - * Reference the page before unlocking - * and sleeping so that the page daemon - * is less likely to reclaim it. - */ - vm_page_lock_queues(); - vm_page_flag_set(m, PG_REFERENCED); - vm_page_sleep(m, "pgtblk"); - continue; - } - - /* - * We have a good page. + * Thus, we specify VM_ALLOC_IGN_SBUSY. */ - vm_page_lock(m); - vm_page_wire(m); - vm_page_unlock(m); + m = vm_page_grab(obj, OFF_TO_IDX(bp->b_offset) + + bp->b_npages, VM_ALLOC_NOBUSY | + VM_ALLOC_SYSTEM | VM_ALLOC_WIRED | + VM_ALLOC_RETRY | VM_ALLOC_IGN_SBUSY | + VM_ALLOC_COUNT(desiredpages - bp->b_npages)); + if (m->valid == 0) + bp->b_flags &= ~B_CACHE; bp->b_pages[bp->b_npages] = m; ++bp->b_npages; } |