Index: sys/fs/tmpfs/tmpfs_vnops.c =================================================================== --- sys/fs/tmpfs/tmpfs_vnops.c (revision 251611) +++ sys/fs/tmpfs/tmpfs_vnops.c (working copy) @@ -487,13 +487,13 @@ tmpfs_nocacheread(vm_object_t tobj, vm_pindex_t id vm_page_zero_invalid(m, TRUE); vm_page_wakeup(m); } - vm_page_lock(m); - vm_page_hold(m); - vm_page_unlock(m); + vm_page_io_start(m); VM_OBJECT_WUNLOCK(tobj); error = uiomove_fromphys(&m, offset, tlen, uio); + VM_OBJECT_WLOCK(tobj); + vm_page_io_finish(m); + VM_OBJECT_WUNLOCK(tobj); vm_page_lock(m); - vm_page_unhold(m); if (m->queue == PQ_NONE) { vm_page_deactivate(m); } else { @@ -604,16 +604,14 @@ tmpfs_mappedwrite(vm_object_t tobj, size_t len, st vm_page_zero_invalid(tpg, TRUE); vm_page_wakeup(tpg); } - vm_page_lock(tpg); - vm_page_hold(tpg); - vm_page_unlock(tpg); + vm_page_io_start(tpg); VM_OBJECT_WUNLOCK(tobj); error = uiomove_fromphys(&tpg, offset, tlen, uio); VM_OBJECT_WLOCK(tobj); if (error == 0) vm_page_dirty(tpg); + vm_page_io_finish(tpg); vm_page_lock(tpg); - vm_page_unhold(tpg); if (tpg->queue == PQ_NONE) { vm_page_deactivate(tpg); } else { Index: sys/vm/vm_glue.c =================================================================== --- sys/vm/vm_glue.c (revision 251611) +++ sys/vm/vm_glue.c (working copy) @@ -233,7 +233,7 @@ vsunlock(void *addr, size_t len) * Return the pinned page if successful; otherwise, return NULL. */ static vm_page_t -vm_imgact_hold_page(vm_object_t object, vm_ooffset_t offset) +vm_imgact_page_iostart(vm_object_t object, vm_ooffset_t offset) { vm_page_t m, ma[1]; vm_pindex_t pindex; @@ -259,9 +259,7 @@ static vm_page_t } vm_page_wakeup(m); } - vm_page_lock(m); - vm_page_hold(m); - vm_page_unlock(m); + vm_page_io_start(m); out: VM_OBJECT_WUNLOCK(object); return (m); @@ -276,7 +274,7 @@ vm_imgact_map_page(vm_object_t object, vm_ooffset_ { vm_page_t m; - m = vm_imgact_hold_page(object, offset); + m = vm_imgact_page_iostart(object, offset); if (m == NULL) return (NULL); sched_pin(); @@ -287,16 +285,16 @@ vm_imgact_map_page(vm_object_t object, vm_ooffset_ * Destroy the given CPU private mapping and unpin the page that it mapped. */ void -vm_imgact_unmap_page(struct sf_buf *sf) +vm_imgact_unmap_page(vm_object_t object, struct sf_buf *sf) { vm_page_t m; m = sf_buf_page(sf); sf_buf_free(sf); sched_unpin(); - vm_page_lock(m); - vm_page_unhold(m); - vm_page_unlock(m); + VM_OBJECT_WLOCK(object); + vm_page_io_finish(m); + VM_OBJECT_WUNLOCK(object); } void Index: sys/vm/vm_extern.h =================================================================== --- sys/vm/vm_extern.h (revision 251611) +++ sys/vm/vm_extern.h (working copy) @@ -87,7 +87,7 @@ void vnode_pager_setsize(struct vnode *, vm_ooffse int vslock(void *, size_t); void vsunlock(void *, size_t); struct sf_buf *vm_imgact_map_page(vm_object_t object, vm_ooffset_t offset); -void vm_imgact_unmap_page(struct sf_buf *sf); +void vm_imgact_unmap_page(vm_object_t, struct sf_buf *sf); void vm_thread_dispose(struct thread *td); int vm_thread_new(struct thread *td, int pages); int vm_mlock(struct proc *, struct ucred *, const void *, size_t); Index: sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c =================================================================== --- sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c (revision 251611) +++ sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c (working copy) @@ -324,7 +324,8 @@ zfs_ioctl(vnode_t *vp, u_long com, intptr_t data, } static vm_page_t -page_busy(vnode_t *vp, int64_t start, int64_t off, int64_t nbytes) +page_busy(vnode_t *vp, int64_t start, int64_t off, int64_t nbytes, + boolean_t alloc) { vm_object_t obj; vm_page_t pp; @@ -345,18 +346,22 @@ static vm_page_t vm_page_sleep(pp, "zfsmwb"); continue; } - } else { + } else + pp = NULL; + + if (pp == NULL && alloc) pp = vm_page_alloc(obj, OFF_TO_IDX(start), VM_ALLOC_SYSTEM | VM_ALLOC_IFCACHED | VM_ALLOC_NOBUSY); - } if (pp != NULL) { ASSERT3U(pp->valid, ==, VM_PAGE_BITS_ALL); - vm_object_pip_add(obj, 1); vm_page_io_start(pp); - pmap_remove_write(pp); - vm_page_clear_dirty(pp, off, nbytes); + if (alloc) { + vm_object_pip_add(obj, 1); + pmap_remove_write(pp); + vm_page_clear_dirty(pp, off, nbytes); + } } break; } @@ -364,57 +369,14 @@ static vm_page_t } static void -page_unbusy(vm_page_t pp) +page_unbusy(vm_page_t pp, boolean_t unalloc) { vm_page_io_finish(pp); - vm_object_pip_subtract(pp->object, 1); + if (unalloc) + vm_object_pip_subtract(pp->object, 1); } -static vm_page_t -page_hold(vnode_t *vp, int64_t start) -{ - vm_object_t obj; - vm_page_t pp; - - obj = vp->v_object; - zfs_vmobject_assert_wlocked(obj); - - for (;;) { - if ((pp = vm_page_lookup(obj, OFF_TO_IDX(start))) != NULL && - pp->valid) { - if ((pp->oflags & VPO_BUSY) != 0) { - /* - * Reference the page before unlocking and - * sleeping so that the page daemon is less - * likely to reclaim it. - */ - vm_page_reference(pp); - vm_page_sleep(pp, "zfsmwb"); - continue; - } - - ASSERT3U(pp->valid, ==, VM_PAGE_BITS_ALL); - vm_page_lock(pp); - vm_page_hold(pp); - vm_page_unlock(pp); - - } else - pp = NULL; - break; - } - return (pp); -} - -static void -page_unhold(vm_page_t pp) -{ - - vm_page_lock(pp); - vm_page_unhold(pp); - vm_page_unlock(pp); -} - static caddr_t zfs_map_page(vm_page_t pp, struct sf_buf **sfp) { @@ -476,7 +438,8 @@ update_pages(vnode_t *vp, int64_t start, int len, zfs_vmobject_wlock(obj); vm_page_undirty(pp); - } else if ((pp = page_busy(vp, start, off, nbytes)) != NULL) { + } else if ((pp = page_busy(vp, start, off, nbytes, + TRUE)) != NULL) { zfs_vmobject_wunlock(obj); va = zfs_map_page(pp, &sf); @@ -485,7 +448,7 @@ update_pages(vnode_t *vp, int64_t start, int len, zfs_unmap_page(sf); zfs_vmobject_wlock(obj); - page_unbusy(pp); + page_unbusy(pp, TRUE); } len -= nbytes; off = 0; @@ -593,7 +556,7 @@ mappedread(vnode_t *vp, int nbytes, uio_t *uio) vm_page_t pp; uint64_t bytes = MIN(PAGESIZE - off, len); - if (pp = page_hold(vp, start)) { + if (pp = page_busy(vp, start, 0, 0, FALSE)) { struct sf_buf *sf; caddr_t va; @@ -602,7 +565,7 @@ mappedread(vnode_t *vp, int nbytes, uio_t *uio) error = uiomove(va + off, bytes, UIO_READ, uio); zfs_unmap_page(sf); zfs_vmobject_wlock(obj); - page_unhold(pp); + page_unbusy(pp, FALSE); } else { zfs_vmobject_wunlock(obj); error = dmu_read_uio(os, zp->z_id, uio, bytes); Index: sys/kern/imgact_elf.c =================================================================== --- sys/kern/imgact_elf.c (revision 251611) +++ sys/kern/imgact_elf.c (working copy) @@ -378,7 +378,7 @@ __elfN(map_partial)(vm_map_t map, vm_object_t obje off = offset - trunc_page(offset); error = copyout((caddr_t)sf_buf_kva(sf) + off, (caddr_t)start, end - start); - vm_imgact_unmap_page(sf); + vm_imgact_unmap_page(object, sf); if (error) { return (KERN_FAILURE); } @@ -433,7 +433,7 @@ __elfN(map_insert)(vm_map_t map, vm_object_t objec sz = PAGE_SIZE - off; error = copyout((caddr_t)sf_buf_kva(sf) + off, (caddr_t)start, sz); - vm_imgact_unmap_page(sf); + vm_imgact_unmap_page(object, sf); if (error) { return (KERN_FAILURE); } @@ -553,7 +553,7 @@ __elfN(load_section)(struct image_params *imgp, vm trunc_page(offset + filsz); error = copyout((caddr_t)sf_buf_kva(sf) + off, (caddr_t)map_addr, copy_len); - vm_imgact_unmap_page(sf); + vm_imgact_unmap_page(object, sf); if (error) { return (error); }