Index: nfsclient/nfs_vnops.c =================================================================== --- nfsclient/nfs_vnops.c (.../head/sys) (revision 247097) +++ nfsclient/nfs_vnops.c (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -629,9 +629,9 @@ nfs_close(struct vop_close_args *ap) * mmap'ed writes or via write(). */ if (nfs_clean_pages_on_close && vp->v_object) { - VM_OBJECT_LOCK(vp->v_object); + VM_OBJECT_WLOCK(vp->v_object); vm_object_page_clean(vp->v_object, 0, 0, 0); - VM_OBJECT_UNLOCK(vp->v_object); + VM_OBJECT_WUNLOCK(vp->v_object); } mtx_lock(&np->n_mtx); if (np->n_flag & NMODIFIED) { Index: nfsclient/nfs_bio.c =================================================================== --- nfsclient/nfs_bio.c (.../head/sys) (revision 247097) +++ nfsclient/nfs_bio.c (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -45,6 +45,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -128,7 +129,7 @@ nfs_getpages(struct vop_getpages_args *ap) * allow the pager to zero-out the blanks. Partially valid pages * can only occur at the file EOF. */ - VM_OBJECT_LOCK(object); + VM_OBJECT_WLOCK(object); if (pages[ap->a_reqpage]->valid != 0) { for (i = 0; i < npages; ++i) { if (i != ap->a_reqpage) { @@ -137,10 +138,10 @@ nfs_getpages(struct vop_getpages_args *ap) vm_page_unlock(pages[i]); } } - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); return (0); } - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); /* * We use only the kva address for the buffer, but this is extremely @@ -170,7 +171,7 @@ nfs_getpages(struct vop_getpages_args *ap) if (error && (uio.uio_resid == count)) { nfs_printf("nfs_getpages: error %d\n", error); - VM_OBJECT_LOCK(object); + VM_OBJECT_WLOCK(object); for (i = 0; i < npages; ++i) { if (i != ap->a_reqpage) { vm_page_lock(pages[i]); @@ -178,7 +179,7 @@ nfs_getpages(struct vop_getpages_args *ap) vm_page_unlock(pages[i]); } } - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); return (VM_PAGER_ERROR); } @@ -189,7 +190,7 @@ nfs_getpages(struct vop_getpages_args *ap) */ size = count - uio.uio_resid; - VM_OBJECT_LOCK(object); + VM_OBJECT_WLOCK(object); for (i = 0, toff = 0; i < npages; i++, toff = nextoff) { vm_page_t m; nextoff = toff + PAGE_SIZE; @@ -225,7 +226,7 @@ nfs_getpages(struct vop_getpages_args *ap) if (i != ap->a_reqpage) vm_page_readahead_finish(m); } - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); return (0); } @@ -1296,9 +1297,9 @@ nfs_vinvalbuf(struct vnode *vp, int flags, struct * Now, flush as required. */ if ((flags & V_SAVE) && (vp->v_bufobj.bo_object != NULL)) { - VM_OBJECT_LOCK(vp->v_bufobj.bo_object); + VM_OBJECT_WLOCK(vp->v_bufobj.bo_object); vm_object_page_clean(vp->v_bufobj.bo_object, 0, 0, OBJPC_SYNC); - VM_OBJECT_UNLOCK(vp->v_bufobj.bo_object); + VM_OBJECT_WUNLOCK(vp->v_bufobj.bo_object); /* * If the page clean was interrupted, fail the invalidation. * Not doing so, we run the risk of losing dirty pages in the Index: i386/i386/pmap.c =================================================================== --- i386/i386/pmap.c (.../head/sys) (revision 247097) +++ i386/i386/pmap.c (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -3456,9 +3456,8 @@ pmap_enter(pmap_t pmap, vm_offset_t va, vm_prot_t KASSERT(va < UPT_MIN_ADDRESS || va >= UPT_MAX_ADDRESS, ("pmap_enter: invalid to pmap_enter page table pages (va: 0x%x)", va)); - KASSERT((m->oflags & (VPO_UNMANAGED | VPO_BUSY)) != 0 || - VM_OBJECT_LOCKED(m->object), - ("pmap_enter: page %p is not busy", m)); + if ((m->oflags & (VPO_UNMANAGED | VPO_BUSY)) == 0) + VM_OBJECT_LOCK_ASSERT(m->object, RA_WLOCKED); mpte = NULL; @@ -3712,7 +3711,7 @@ pmap_enter_object(pmap_t pmap, vm_offset_t start, vm_page_t m, mpte; vm_pindex_t diff, psize; - VM_OBJECT_LOCK_ASSERT(m_start->object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(m_start->object, RA_WLOCKED); psize = atop(end - start); mpte = NULL; m = m_start; @@ -3890,7 +3889,7 @@ pmap_object_init_pt(pmap_t pmap, vm_offset_t addr, vm_page_t p; int pat_mode; - VM_OBJECT_LOCK_ASSERT(object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(object, RA_WLOCKED); KASSERT(object->type == OBJT_DEVICE || object->type == OBJT_SG, ("pmap_object_init_pt: non-device object")); if (pseflag && @@ -4509,7 +4508,7 @@ pmap_is_modified(vm_page_t m) * concurrently set while the object is locked. Thus, if PGA_WRITEABLE * is clear, no PTEs can have PG_M set. */ - VM_OBJECT_LOCK_ASSERT(m->object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(m->object, RA_WLOCKED); if ((m->oflags & VPO_BUSY) == 0 && (m->aflags & PGA_WRITEABLE) == 0) return (FALSE); @@ -4644,7 +4643,7 @@ pmap_remove_write(vm_page_t m) * another thread while the object is locked. Thus, if PGA_WRITEABLE * is clear, no page table entries need updating. */ - VM_OBJECT_LOCK_ASSERT(m->object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(m->object, RA_WLOCKED); if ((m->oflags & VPO_BUSY) == 0 && (m->aflags & PGA_WRITEABLE) == 0) return; @@ -4796,7 +4795,7 @@ pmap_clear_modify(vm_page_t m) KASSERT((m->oflags & VPO_UNMANAGED) == 0, ("pmap_clear_modify: page %p is not managed", m)); - VM_OBJECT_LOCK_ASSERT(m->object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(m->object, RA_WLOCKED); KASSERT((m->oflags & VPO_BUSY) == 0, ("pmap_clear_modify: page %p is busy", m)); Index: i386/i386/machdep.c =================================================================== --- i386/i386/machdep.c (.../head/sys) (revision 247097) +++ i386/i386/machdep.c (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -81,6 +81,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #ifdef SMP Index: i386/xen/pmap.c =================================================================== --- i386/xen/pmap.c (.../head/sys) (revision 247097) +++ i386/xen/pmap.c (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -2666,9 +2666,8 @@ pmap_enter(pmap_t pmap, vm_offset_t va, vm_prot_t KASSERT(va < UPT_MIN_ADDRESS || va >= UPT_MAX_ADDRESS, ("pmap_enter: invalid to pmap_enter page table pages (va: 0x%x)", va)); - KASSERT((m->oflags & (VPO_UNMANAGED | VPO_BUSY)) != 0 || - VM_OBJECT_LOCKED(m->object), - ("pmap_enter: page %p is not busy", m)); + if ((m->oflags & (VPO_UNMANAGED | VPO_BUSY)) == 0) + VM_OBJECT_LOCK_ASSERT(m->object, RA_WLOCKED); mpte = NULL; @@ -2871,7 +2870,7 @@ pmap_enter_object(pmap_t pmap, vm_offset_t start, multicall_entry_t *mclp = mcl; int error, count = 0; - VM_OBJECT_LOCK_ASSERT(m_start->object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(m_start->object, RA_WLOCKED); psize = atop(end - start); mpte = NULL; m = m_start; @@ -3111,7 +3110,7 @@ pmap_object_init_pt(pmap_t pmap, vm_offset_t addr, vm_page_t p; int pat_mode; - VM_OBJECT_LOCK_ASSERT(object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(object, RA_WLOCKED); KASSERT(object->type == OBJT_DEVICE || object->type == OBJT_SG, ("pmap_object_init_pt: non-device object")); if (pseflag && @@ -3657,7 +3656,7 @@ pmap_is_modified(vm_page_t m) * concurrently set while the object is locked. Thus, if PGA_WRITEABLE * is clear, no PTEs can have PG_M set. */ - VM_OBJECT_LOCK_ASSERT(m->object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(m->object, RA_WLOCKED); if ((m->oflags & VPO_BUSY) == 0 && (m->aflags & PGA_WRITEABLE) == 0) return (rv); @@ -3788,7 +3787,7 @@ pmap_remove_write(vm_page_t m) * another thread while the object is locked. Thus, if PGA_WRITEABLE * is clear, no page table entries need updating. */ - VM_OBJECT_LOCK_ASSERT(m->object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(m->object, RA_WLOCKED); if ((m->oflags & VPO_BUSY) == 0 && (m->aflags & PGA_WRITEABLE) == 0) return; @@ -3889,7 +3888,7 @@ pmap_clear_modify(vm_page_t m) KASSERT((m->oflags & VPO_UNMANAGED) == 0, ("pmap_clear_modify: page %p is not managed", m)); - VM_OBJECT_LOCK_ASSERT(m->object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(m->object, RA_WLOCKED); KASSERT((m->oflags & VPO_BUSY) == 0, ("pmap_clear_modify: page %p is busy", m)); Index: ufs/ffs/ffs_rawread.c =================================================================== --- ufs/ffs/ffs_rawread.c (.../head/sys) (revision 247097) +++ ufs/ffs/ffs_rawread.c (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -42,6 +42,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -143,9 +144,9 @@ ffs_rawread_sync(struct vnode *vp) if ((obj = vp->v_object) != NULL && (obj->flags & OBJ_MIGHTBEDIRTY) != 0) { VI_UNLOCK(vp); - VM_OBJECT_LOCK(obj); + VM_OBJECT_WLOCK(obj); vm_object_page_clean(obj, 0, 0, OBJPC_SYNC); - VM_OBJECT_UNLOCK(obj); + VM_OBJECT_WUNLOCK(obj); } else VI_UNLOCK(vp); Index: ufs/ffs/ffs_vnops.c =================================================================== --- ufs/ffs/ffs_vnops.c (.../head/sys) (revision 247097) +++ ufs/ffs/ffs_vnops.c (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -75,6 +75,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -842,7 +843,7 @@ ffs_getpages(ap) * user programs might reference data beyond the actual end of file * occuring within the page. We have to zero that data. */ - VM_OBJECT_LOCK(mreq->object); + VM_OBJECT_WLOCK(mreq->object); if (mreq->valid) { if (mreq->valid != VM_PAGE_BITS_ALL) vm_page_zero_invalid(mreq, TRUE); @@ -853,10 +854,10 @@ ffs_getpages(ap) vm_page_unlock(ap->a_m[i]); } } - VM_OBJECT_UNLOCK(mreq->object); + VM_OBJECT_WUNLOCK(mreq->object); return VM_PAGER_OK; } - VM_OBJECT_UNLOCK(mreq->object); + VM_OBJECT_WUNLOCK(mreq->object); return vnode_pager_generic_getpages(ap->a_vp, ap->a_m, ap->a_count, Index: cddl/compat/opensolaris/sys/freebsd_rwlock.h =================================================================== --- cddl/compat/opensolaris/sys/freebsd_rwlock.h (.../head/sys) (revision 0) +++ cddl/compat/opensolaris/sys/freebsd_rwlock.h (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -0,0 +1,34 @@ +/*- + * Copyright (c) 2013 EMC Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _OPENSOLARIS_SYS_FREEBSD_RWLOCK_H_ +#define _OPENSOLARIS_SYS_FREEBSD_RWLOCK_H_ + +#include_next + +#endif Property changes on: cddl/compat/opensolaris/sys/freebsd_rwlock.h ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native Added: svn:mime-type ## -0,0 +1 ## +text/plain Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H Index: cddl/compat/opensolaris/sys/vm.h =================================================================== --- cddl/compat/opensolaris/sys/vm.h (.../head/sys) (revision 0) +++ cddl/compat/opensolaris/sys/vm.h (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -0,0 +1,44 @@ +/*- + * Copyright (c) 2013 EMC Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _OPENSOLARIS_SYS_VM_H_ +#define _OPENSOLARIS_SYS_VM_H_ + +#ifdef _KERNEL + +int vm_pagerret_bad(void); +int vm_pagerret_error(void); +int vm_pagerret_ok(void); + +void zfs_vmobject_assert_wlocked(vm_object_t object); +void zfs_vmobject_wlock(vm_object_t object); +void zfs_vmobject_wunlock(vm_object_t object); + +#endif /* _KERNEL */ + +#endif /* _OPENSOLARIS_SYS_VM_H_ */ Property changes on: cddl/compat/opensolaris/sys/vm.h ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +text/plain Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H Added: svn:eol-style ## -0,0 +1 ## +native Index: cddl/compat/opensolaris/kern/opensolaris_vm.c =================================================================== --- cddl/compat/opensolaris/kern/opensolaris_vm.c (.../head/sys) (revision 0) +++ cddl/compat/opensolaris/kern/opensolaris_vm.c (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -0,0 +1,84 @@ +/*- + * Copyright (c) 2013 EMC Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include + +int +vm_pagerret_bad(void) +{ + + return (VM_PAGER_BAD); +} + +int +vm_pagerret_error(void) +{ + + return (VM_PAGER_ERROR); +} + +int +vm_pagerret_ok(void) +{ + + return (VM_PAGER_OK); +} + +void +zfs_vmobject_assert_wlocked(vm_object_t object) +{ + + /* + * This is not ideal because FILE/LINE used by assertions will not + * be too helpful, but it must be an hard function for + * compatibility reasons. + */ + VM_OBJECT_LOCK_ASSERT(object, RA_WLOCKED); +} + +void +zfs_vmobject_wlock(vm_object_t object) +{ + + VM_OBJECT_WLOCK(object); +} + +void +zfs_vmobject_wunlock(vm_object_t object) +{ + + VM_OBJECT_WUNLOCK(object); +} Property changes on: cddl/compat/opensolaris/kern/opensolaris_vm.c ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native Added: svn:mime-type ## -0,0 +1 ## +text/plain Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H Index: cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_context.h =================================================================== --- cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_context.h (.../head/sys) (revision 247097) +++ cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_context.h (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -94,7 +94,6 @@ extern "C" { #include #include #include -#include #include #include /* There is clash. vm_map.h defines the two below and vdev_cache.c use them. */ Index: cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c =================================================================== --- cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c (.../head/sys) (revision 247097) +++ cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -329,7 +330,7 @@ page_busy(vnode_t *vp, int64_t start, int64_t off, vm_page_t pp; obj = vp->v_object; - VM_OBJECT_LOCK_ASSERT(obj, MA_OWNED); + zfs_vmobject_assert_wlocked(obj); for (;;) { if ((pp = vm_page_lookup(obj, OFF_TO_IDX(start))) != NULL && @@ -377,7 +378,7 @@ page_hold(vnode_t *vp, int64_t start) vm_page_t pp; obj = vp->v_object; - VM_OBJECT_LOCK_ASSERT(obj, MA_OWNED); + zfs_vmobject_assert_wlocked(obj); for (;;) { if ((pp = vm_page_lookup(obj, OFF_TO_IDX(start))) != NULL && @@ -450,7 +451,7 @@ update_pages(vnode_t *vp, int64_t start, int len, ASSERT(obj != NULL); off = start & PAGEOFFSET; - VM_OBJECT_LOCK(obj); + zfs_vmobject_wlock(obj); for (start &= PAGEMASK; len > 0; start += PAGESIZE) { vm_page_t pp; int nbytes = imin(PAGESIZE - off, len); @@ -467,23 +468,23 @@ update_pages(vnode_t *vp, int64_t start, int len, ("zfs update_pages: unbusy page in putpages case")); KASSERT(!pmap_page_is_write_mapped(pp), ("zfs update_pages: writable page in putpages case")); - VM_OBJECT_UNLOCK(obj); + zfs_vmobject_wunlock(obj); va = zfs_map_page(pp, &sf); (void) dmu_write(os, oid, start, nbytes, va, tx); zfs_unmap_page(sf); - VM_OBJECT_LOCK(obj); + zfs_vmobject_wlock(obj); vm_page_undirty(pp); } else if ((pp = page_busy(vp, start, off, nbytes)) != NULL) { - VM_OBJECT_UNLOCK(obj); + zfs_vmobject_wunlock(obj); va = zfs_map_page(pp, &sf); (void) dmu_read(os, oid, start+off, nbytes, va+off, DMU_READ_PREFETCH);; zfs_unmap_page(sf); - VM_OBJECT_LOCK(obj); + zfs_vmobject_wlock(obj); page_unbusy(pp); } len -= nbytes; @@ -491,7 +492,7 @@ update_pages(vnode_t *vp, int64_t start, int len, } if (segflg != UIO_NOCOPY) vm_object_pip_wakeupn(obj, 0); - VM_OBJECT_UNLOCK(obj); + zfs_vmobject_wunlock(obj); } /* @@ -523,7 +524,7 @@ mappedread_sf(vnode_t *vp, int nbytes, uio_t *uio) ASSERT(obj != NULL); ASSERT((uio->uio_loffset & PAGEOFFSET) == 0); - VM_OBJECT_LOCK(obj); + zfs_vmobject_wlock(obj); for (start = uio->uio_loffset; len > 0; start += PAGESIZE) { int bytes = MIN(PAGESIZE, len); @@ -531,14 +532,14 @@ mappedread_sf(vnode_t *vp, int nbytes, uio_t *uio) VM_ALLOC_NORMAL | VM_ALLOC_RETRY | VM_ALLOC_IGN_SBUSY); if (pp->valid == 0) { vm_page_io_start(pp); - VM_OBJECT_UNLOCK(obj); + zfs_vmobject_wunlock(obj); va = zfs_map_page(pp, &sf); error = dmu_read(os, zp->z_id, start, bytes, va, DMU_READ_PREFETCH); if (bytes != PAGESIZE && error == 0) bzero(va + bytes, PAGESIZE - bytes); zfs_unmap_page(sf); - VM_OBJECT_LOCK(obj); + zfs_vmobject_wlock(obj); vm_page_io_finish(pp); vm_page_lock(pp); if (error) { @@ -555,7 +556,7 @@ mappedread_sf(vnode_t *vp, int nbytes, uio_t *uio) uio->uio_offset += bytes; len -= bytes; } - VM_OBJECT_UNLOCK(obj); + zfs_vmobject_wunlock(obj); return (error); } @@ -587,7 +588,7 @@ mappedread(vnode_t *vp, int nbytes, uio_t *uio) start = uio->uio_loffset; off = start & PAGEOFFSET; - VM_OBJECT_LOCK(obj); + zfs_vmobject_wlock(obj); for (start &= PAGEMASK; len > 0; start += PAGESIZE) { vm_page_t pp; uint64_t bytes = MIN(PAGESIZE - off, len); @@ -596,23 +597,23 @@ mappedread(vnode_t *vp, int nbytes, uio_t *uio) struct sf_buf *sf; caddr_t va; - VM_OBJECT_UNLOCK(obj); + zfs_vmobject_wunlock(obj); va = zfs_map_page(pp, &sf); error = uiomove(va + off, bytes, UIO_READ, uio); zfs_unmap_page(sf); - VM_OBJECT_LOCK(obj); + zfs_vmobject_wlock(obj); page_unhold(pp); } else { - VM_OBJECT_UNLOCK(obj); + zfs_vmobject_wunlock(obj); error = dmu_read_uio(os, zp->z_id, uio, bytes); - VM_OBJECT_LOCK(obj); + zfs_vmobject_wlock(obj); } len -= bytes; off = 0; if (error) break; } - VM_OBJECT_UNLOCK(obj); + zfs_vmobject_wunlock(obj); return (error); } @@ -5683,7 +5684,7 @@ zfs_getpages(struct vnode *vp, vm_page_t *m, int c mfirst = m[reqstart]; mlast = m[reqstart + reqsize - 1]; - VM_OBJECT_LOCK(object); + zfs_vmobject_wlock(object); for (i = 0; i < reqstart; i++) { vm_page_lock(m[i]); @@ -5699,9 +5700,9 @@ zfs_getpages(struct vnode *vp, vm_page_t *m, int c if (mreq->valid && reqsize == 1) { if (mreq->valid != VM_PAGE_BITS_ALL) vm_page_zero_invalid(mreq, TRUE); - VM_OBJECT_UNLOCK(object); + zfs_vmobject_wunlock(object); ZFS_EXIT(zfsvfs); - return (VM_PAGER_OK); + return (vm_pagerret_ok()); } PCPU_INC(cnt.v_vnodein); @@ -5715,16 +5716,16 @@ zfs_getpages(struct vnode *vp, vm_page_t *m, int c vm_page_unlock(m[i]); } } - VM_OBJECT_UNLOCK(object); + zfs_vmobject_wunlock(object); ZFS_EXIT(zfsvfs); - return (VM_PAGER_BAD); + return (vm_pagerret_bad()); } lsize = PAGE_SIZE; if (IDX_TO_OFF(mlast->pindex) + lsize > object->un_pager.vnp.vnp_size) lsize = object->un_pager.vnp.vnp_size - IDX_TO_OFF(mlast->pindex); - VM_OBJECT_UNLOCK(object); + zfs_vmobject_wunlock(object); for (i = reqstart; i < reqstart + reqsize; i++) { size = PAGE_SIZE; @@ -5740,7 +5741,7 @@ zfs_getpages(struct vnode *vp, vm_page_t *m, int c break; } - VM_OBJECT_LOCK(object); + zfs_vmobject_wlock(object); for (i = reqstart; i < reqstart + reqsize; i++) { if (!error) @@ -5750,11 +5751,11 @@ zfs_getpages(struct vnode *vp, vm_page_t *m, int c vm_page_readahead_finish(m[i]); } - VM_OBJECT_UNLOCK(object); + zfs_vmobject_wunlock(object); ZFS_ACCESSTIME_STAMP(zfsvfs, zp); ZFS_EXIT(zfsvfs); - return (error ? VM_PAGER_ERROR : VM_PAGER_OK); + return (error ? vm_pagerret_error() : vm_pagerret_ok()); } static int Index: cddl/contrib/opensolaris =================================================================== --- cddl/contrib/opensolaris (.../head/sys) (revision 247097) +++ cddl/contrib/opensolaris (.../user/attilio/vmobj-rwlock/sys) (revision 247097) Property changes on: cddl/contrib/opensolaris ___________________________________________________________________ Modified: svn:mergeinfo Merged /head/sys/cddl/contrib/opensolaris:r247016-247096 Index: security/mac/mac_process.c =================================================================== --- security/mac/mac_process.c (.../head/sys) (revision 247097) +++ security/mac/mac_process.c (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -54,9 +54,9 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include #include +#include #include #include #include @@ -284,14 +284,14 @@ mac_proc_vm_revoke_recurse(struct thread *td, stru object = vme->object.vm_object; if (object == NULL) continue; - VM_OBJECT_LOCK(object); + VM_OBJECT_WLOCK(object); while ((backing_object = object->backing_object) != NULL) { - VM_OBJECT_LOCK(backing_object); + VM_OBJECT_WLOCK(backing_object); offset += object->backing_object_offset; - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); object = backing_object; } - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); /* * At the moment, vm_maps and objects aren't considered by * the MAC system, so only things with backing by a normal @@ -334,10 +334,10 @@ mac_proc_vm_revoke_recurse(struct thread *td, stru vm_object_reference(object); (void) vn_start_write(vp, &mp, V_WAIT); vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); - VM_OBJECT_LOCK(object); + VM_OBJECT_WLOCK(object); vm_object_page_clean(object, offset, offset + vme->end - vme->start, OBJPC_SYNC); - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); VOP_UNLOCK(vp, 0); vn_finished_write(mp); vm_object_deallocate(object); Index: modules/zfs/Makefile =================================================================== --- modules/zfs/Makefile (.../head/sys) (revision 247097) +++ modules/zfs/Makefile (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -28,6 +28,7 @@ SRCS+= opensolaris_sysevent.c SRCS+= opensolaris_taskq.c SRCS+= opensolaris_uio.c SRCS+= opensolaris_vfs.c +SRCS+= opensolaris_vm.c SRCS+= opensolaris_zone.c _A=${.CURDIR}/../../cddl/contrib/opensolaris/common/atomic Index: nfsserver/nfs_serv.c =================================================================== --- nfsserver/nfs_serv.c (.../head/sys) (revision 247097) +++ nfsserver/nfs_serv.c (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -87,6 +87,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -3332,9 +3333,9 @@ nfsrv_commit(struct nfsrv_descript *nfsd, struct n */ if (vp->v_object && (vp->v_object->flags & OBJ_MIGHTBEDIRTY)) { - VM_OBJECT_LOCK(vp->v_object); + VM_OBJECT_WLOCK(vp->v_object); vm_object_page_clean(vp->v_object, 0, 0, OBJPC_SYNC); - VM_OBJECT_UNLOCK(vp->v_object); + VM_OBJECT_WUNLOCK(vp->v_object); } error = VOP_FSYNC(vp, MNT_WAIT, curthread); } else { @@ -3363,10 +3364,10 @@ nfsrv_commit(struct nfsrv_descript *nfsd, struct n if (vp->v_object && (vp->v_object->flags & OBJ_MIGHTBEDIRTY)) { - VM_OBJECT_LOCK(vp->v_object); + VM_OBJECT_WLOCK(vp->v_object); vm_object_page_clean(vp->v_object, off, off + cnt, OBJPC_SYNC); - VM_OBJECT_UNLOCK(vp->v_object); + VM_OBJECT_WUNLOCK(vp->v_object); } bo = &vp->v_bufobj; Index: dev/md/md.c =================================================================== --- dev/md/md.c (.../head/sys) (revision 247097) +++ dev/md/md.c (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -75,6 +75,7 @@ #include #include #include +#include #include #include #include @@ -657,17 +658,17 @@ mdstart_swap(struct md_s *sc, struct bio *bp) lastend = (bp->bio_offset + bp->bio_length - 1) % PAGE_SIZE + 1; rv = VM_PAGER_OK; - VM_OBJECT_LOCK(sc->object); + VM_OBJECT_WLOCK(sc->object); vm_object_pip_add(sc->object, 1); for (i = bp->bio_offset / PAGE_SIZE; i <= lastp; i++) { len = ((i == lastp) ? lastend : PAGE_SIZE) - offs; m = vm_page_grab(sc->object, i, VM_ALLOC_NORMAL|VM_ALLOC_RETRY); - VM_OBJECT_UNLOCK(sc->object); + VM_OBJECT_WUNLOCK(sc->object); sched_pin(); sf = sf_buf_alloc(m, SFB_CPUPRIVATE); - VM_OBJECT_LOCK(sc->object); + VM_OBJECT_WLOCK(sc->object); if (bp->bio_cmd == BIO_READ) { if (m->valid != VM_PAGE_BITS_ALL) rv = vm_pager_get_pages(sc->object, &m, 1, 0); @@ -732,7 +733,7 @@ mdstart_swap(struct md_s *sc, struct bio *bp) offs = 0; } vm_object_pip_subtract(sc->object, 1); - VM_OBJECT_UNLOCK(sc->object); + VM_OBJECT_WUNLOCK(sc->object); return (rv != VM_PAGER_ERROR ? 0 : ENOSPC); } @@ -1068,7 +1069,7 @@ mdresize(struct md_s *sc, struct md_ioctl *mdio) oldpages = OFF_TO_IDX(round_page(sc->mediasize)); newpages = OFF_TO_IDX(round_page(mdio->md_mediasize)); if (newpages < oldpages) { - VM_OBJECT_LOCK(sc->object); + VM_OBJECT_WLOCK(sc->object); vm_object_page_remove(sc->object, newpages, 0, 0); swap_pager_freespace(sc->object, newpages, oldpages - newpages); @@ -1076,7 +1077,7 @@ mdresize(struct md_s *sc, struct md_ioctl *mdio) newpages), sc->cred); sc->object->charge = IDX_TO_OFF(newpages); sc->object->size = newpages; - VM_OBJECT_UNLOCK(sc->object); + VM_OBJECT_WUNLOCK(sc->object); } else if (newpages > oldpages) { res = swap_reserve_by_cred(IDX_TO_OFF(newpages - oldpages), sc->cred); @@ -1093,10 +1094,10 @@ mdresize(struct md_s *sc, struct md_ioctl *mdio) return (EDOM); } } - VM_OBJECT_LOCK(sc->object); + VM_OBJECT_WLOCK(sc->object); sc->object->charge = IDX_TO_OFF(newpages); sc->object->size = newpages; - VM_OBJECT_UNLOCK(sc->object); + VM_OBJECT_WUNLOCK(sc->object); } break; default: Index: dev/netmap/netmap.c =================================================================== --- dev/netmap/netmap.c (.../head/sys) (revision 247097) +++ dev/netmap/netmap.c (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -81,6 +81,7 @@ __FBSDID("$FreeBSD$"); #include /* PROT_EXEC */ #include #include +#include #include /* vtophys */ #include /* vtophys */ #include /* sockaddrs */ Index: dev/sound/pcm/dsp.c =================================================================== --- dev/sound/pcm/dsp.c (.../head/sys) (revision 247097) +++ dev/sound/pcm/dsp.c (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -32,6 +32,8 @@ #include #include +#include +#include #include #include Index: dev/agp/agp.c =================================================================== --- dev/agp/agp.c (.../head/sys) (revision 247097) +++ dev/agp/agp.c (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -41,6 +41,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -544,7 +545,7 @@ agp_generic_bind_memory(device_t dev, struct agp_m * because vm_page_grab() may sleep and we can't hold a mutex * while sleeping. */ - VM_OBJECT_LOCK(mem->am_obj); + VM_OBJECT_WLOCK(mem->am_obj); for (i = 0; i < mem->am_size; i += PAGE_SIZE) { /* * Find a page from the object and wire it @@ -557,14 +558,14 @@ agp_generic_bind_memory(device_t dev, struct agp_m VM_ALLOC_WIRED | VM_ALLOC_ZERO | VM_ALLOC_RETRY); AGP_DPF("found page pa=%#jx\n", (uintmax_t)VM_PAGE_TO_PHYS(m)); } - VM_OBJECT_UNLOCK(mem->am_obj); + VM_OBJECT_WUNLOCK(mem->am_obj); mtx_lock(&sc->as_lock); if (mem->am_is_bound) { device_printf(dev, "memory already bound\n"); error = EINVAL; - VM_OBJECT_LOCK(mem->am_obj); + VM_OBJECT_WLOCK(mem->am_obj); i = 0; goto bad; } @@ -573,7 +574,7 @@ agp_generic_bind_memory(device_t dev, struct agp_m * Bind the individual pages and flush the chipset's * TLB. */ - VM_OBJECT_LOCK(mem->am_obj); + VM_OBJECT_WLOCK(mem->am_obj); for (i = 0; i < mem->am_size; i += PAGE_SIZE) { m = vm_page_lookup(mem->am_obj, OFF_TO_IDX(i)); @@ -601,7 +602,7 @@ agp_generic_bind_memory(device_t dev, struct agp_m } vm_page_wakeup(m); } - VM_OBJECT_UNLOCK(mem->am_obj); + VM_OBJECT_WUNLOCK(mem->am_obj); /* * Flush the cpu cache since we are providing a new mapping @@ -622,7 +623,7 @@ agp_generic_bind_memory(device_t dev, struct agp_m return 0; bad: mtx_unlock(&sc->as_lock); - VM_OBJECT_LOCK_ASSERT(mem->am_obj, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(mem->am_obj, RA_WLOCKED); for (k = 0; k < mem->am_size; k += PAGE_SIZE) { m = vm_page_lookup(mem->am_obj, OFF_TO_IDX(k)); if (k >= i) @@ -631,7 +632,7 @@ bad: vm_page_unwire(m, 0); vm_page_unlock(m); } - VM_OBJECT_UNLOCK(mem->am_obj); + VM_OBJECT_WUNLOCK(mem->am_obj); return error; } @@ -658,14 +659,14 @@ agp_generic_unbind_memory(device_t dev, struct agp */ for (i = 0; i < mem->am_size; i += AGP_PAGE_SIZE) AGP_UNBIND_PAGE(dev, mem->am_offset + i); - VM_OBJECT_LOCK(mem->am_obj); + VM_OBJECT_WLOCK(mem->am_obj); for (i = 0; i < mem->am_size; i += PAGE_SIZE) { m = vm_page_lookup(mem->am_obj, atop(i)); vm_page_lock(m); vm_page_unwire(m, 0); vm_page_unlock(m); } - VM_OBJECT_UNLOCK(mem->am_obj); + VM_OBJECT_WUNLOCK(mem->am_obj); agp_flush_cache(); AGP_FLUSH_TLB(dev); Index: dev/agp/agp_i810.c =================================================================== --- dev/agp/agp_i810.c (.../head/sys) (revision 247097) +++ dev/agp/agp_i810.c (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -56,6 +56,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -1967,10 +1968,10 @@ agp_i810_alloc_memory(device_t dev, int type, vm_s * Allocate and wire down the page now so that we can * get its physical address. */ - VM_OBJECT_LOCK(mem->am_obj); + VM_OBJECT_WLOCK(mem->am_obj); m = vm_page_grab(mem->am_obj, 0, VM_ALLOC_NOBUSY | VM_ALLOC_WIRED | VM_ALLOC_ZERO | VM_ALLOC_RETRY); - VM_OBJECT_UNLOCK(mem->am_obj); + VM_OBJECT_WUNLOCK(mem->am_obj); mem->am_physical = VM_PAGE_TO_PHYS(m); } else { /* Our allocation is already nicely wired down for us. @@ -2005,12 +2006,12 @@ agp_i810_free_memory(device_t dev, struct agp_memo /* * Unwire the page which we wired in alloc_memory. */ - VM_OBJECT_LOCK(mem->am_obj); + VM_OBJECT_WLOCK(mem->am_obj); m = vm_page_lookup(mem->am_obj, 0); vm_page_lock(m); vm_page_unwire(m, 0); vm_page_unlock(m); - VM_OBJECT_UNLOCK(mem->am_obj); + VM_OBJECT_WUNLOCK(mem->am_obj); } else { contigfree(sc->argb_cursor, mem->am_size, M_AGP); sc->argb_cursor = NULL; Index: dev/hwpmc/hwpmc_mod.c =================================================================== --- dev/hwpmc/hwpmc_mod.c (.../head/sys) (revision 247097) +++ dev/hwpmc/hwpmc_mod.c (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -50,6 +50,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -1671,7 +1672,7 @@ pmc_log_process_mappings(struct pmc_owner *po, str } obj = entry->object.vm_object; - VM_OBJECT_LOCK(obj); + VM_OBJECT_WLOCK(obj); /* * Walk the backing_object list to find the base @@ -1679,9 +1680,9 @@ pmc_log_process_mappings(struct pmc_owner *po, str */ for (lobj = tobj = obj; tobj != NULL; tobj = tobj->backing_object) { if (tobj != obj) - VM_OBJECT_LOCK(tobj); + VM_OBJECT_WLOCK(tobj); if (lobj != obj) - VM_OBJECT_UNLOCK(lobj); + VM_OBJECT_WUNLOCK(lobj); lobj = tobj; } @@ -1691,14 +1692,14 @@ pmc_log_process_mappings(struct pmc_owner *po, str if (lobj == NULL) { PMCDBG(LOG,OPS,2, "hwpmc: lobj unexpectedly NULL! pid=%d " "vm_map=%p vm_obj=%p\n", p->p_pid, map, obj); - VM_OBJECT_UNLOCK(obj); + VM_OBJECT_WUNLOCK(obj); continue; } if (lobj->type != OBJT_VNODE || lobj->handle == NULL) { if (lobj != obj) - VM_OBJECT_UNLOCK(lobj); - VM_OBJECT_UNLOCK(obj); + VM_OBJECT_WUNLOCK(lobj); + VM_OBJECT_WUNLOCK(obj); continue; } @@ -1710,8 +1711,8 @@ pmc_log_process_mappings(struct pmc_owner *po, str if (entry->start == last_end && lobj->handle == last_vp) { last_end = entry->end; if (lobj != obj) - VM_OBJECT_UNLOCK(lobj); - VM_OBJECT_UNLOCK(obj); + VM_OBJECT_WUNLOCK(lobj); + VM_OBJECT_WUNLOCK(obj); continue; } @@ -1733,9 +1734,9 @@ pmc_log_process_mappings(struct pmc_owner *po, str vp = lobj->handle; vref(vp); if (lobj != obj) - VM_OBJECT_UNLOCK(lobj); + VM_OBJECT_WUNLOCK(lobj); - VM_OBJECT_UNLOCK(obj); + VM_OBJECT_WUNLOCK(obj); freepath = NULL; pmc_getfilename(vp, &fullpath, &freepath); Index: dev/drm/drmP.h =================================================================== --- dev/drm/drmP.h (.../head/sys) (revision 247097) +++ dev/drm/drmP.h (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -59,6 +59,7 @@ struct drm_file; #include #include #include +#include #include #include #include Index: dev/drm2/i915/i915_gem.c =================================================================== --- dev/drm2/i915/i915_gem.c (.../head/sys) (revision 247097) +++ dev/drm2/i915/i915_gem.c (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -990,14 +990,14 @@ i915_gem_swap_io(struct drm_device *dev, struct dr vm_obj = obj->base.vm_obj; ret = 0; - VM_OBJECT_LOCK(vm_obj); + VM_OBJECT_WLOCK(vm_obj); vm_object_pip_add(vm_obj, 1); while (size > 0) { obj_pi = OFF_TO_IDX(offset); obj_po = offset & PAGE_MASK; m = i915_gem_wire_page(vm_obj, obj_pi); - VM_OBJECT_UNLOCK(vm_obj); + VM_OBJECT_WUNLOCK(vm_obj); sched_pin(); sf = sf_buf_alloc(m, SFB_CPUPRIVATE); @@ -1031,7 +1031,7 @@ i915_gem_swap_io(struct drm_device *dev, struct dr } sf_buf_free(sf); sched_unpin(); - VM_OBJECT_LOCK(vm_obj); + VM_OBJECT_WLOCK(vm_obj); if (rw == UIO_WRITE) vm_page_dirty(m); vm_page_reference(m); @@ -1044,7 +1044,7 @@ i915_gem_swap_io(struct drm_device *dev, struct dr break; } vm_object_pip_wakeup(vm_obj); - VM_OBJECT_UNLOCK(vm_obj); + VM_OBJECT_WUNLOCK(vm_obj); return (ret); } @@ -1357,7 +1357,7 @@ i915_gem_pager_fault(vm_object_t vm_obj, vm_ooffse } else oldm = NULL; retry: - VM_OBJECT_UNLOCK(vm_obj); + VM_OBJECT_WUNLOCK(vm_obj); unlocked_vmobj: cause = ret = 0; m = NULL; @@ -1407,7 +1407,7 @@ unlocked_vmobj: list_move_tail(&obj->mm_list, &dev_priv->mm.inactive_list); obj->fault_mappable = true; - VM_OBJECT_LOCK(vm_obj); + VM_OBJECT_WLOCK(vm_obj); m = vm_phys_fictitious_to_vm_page(dev->agp->base + obj->gtt_offset + offset); if (m == NULL) { @@ -1452,7 +1452,7 @@ out: kern_yield(PRI_USER); goto unlocked_vmobj; } - VM_OBJECT_LOCK(vm_obj); + VM_OBJECT_WLOCK(vm_obj); vm_object_pip_wakeup(vm_obj); return (VM_PAGER_ERROR); } @@ -2208,12 +2208,12 @@ i915_gem_object_get_pages_gtt(struct drm_i915_gem_ obj->pages = malloc(page_count * sizeof(vm_page_t), DRM_I915_GEM, M_WAITOK); vm_obj = obj->base.vm_obj; - VM_OBJECT_LOCK(vm_obj); + VM_OBJECT_WLOCK(vm_obj); for (i = 0; i < page_count; i++) { if ((obj->pages[i] = i915_gem_wire_page(vm_obj, i)) == NULL) goto failed; } - VM_OBJECT_UNLOCK(vm_obj); + VM_OBJECT_WUNLOCK(vm_obj); if (i915_gem_object_needs_bit17_swizzle(obj)) i915_gem_object_do_bit_17_swizzle(obj); return (0); @@ -2226,7 +2226,7 @@ failed: vm_page_unlock(m); atomic_add_long(&i915_gem_wired_pages_cnt, -1); } - VM_OBJECT_UNLOCK(vm_obj); + VM_OBJECT_WUNLOCK(vm_obj); free(obj->pages, DRM_I915_GEM); obj->pages = NULL; return (-EIO); @@ -2272,7 +2272,7 @@ i915_gem_object_put_pages_gtt(struct drm_i915_gem_ if (obj->madv == I915_MADV_DONTNEED) obj->dirty = 0; page_count = obj->base.size / PAGE_SIZE; - VM_OBJECT_LOCK(obj->base.vm_obj); + VM_OBJECT_WLOCK(obj->base.vm_obj); #if GEM_PARANOID_CHECK_GTT i915_gem_assert_pages_not_mapped(obj->base.dev, obj->pages, page_count); #endif @@ -2287,7 +2287,7 @@ i915_gem_object_put_pages_gtt(struct drm_i915_gem_ vm_page_unlock(m); atomic_add_long(&i915_gem_wired_pages_cnt, -1); } - VM_OBJECT_UNLOCK(obj->base.vm_obj); + VM_OBJECT_WUNLOCK(obj->base.vm_obj); obj->dirty = 0; free(obj->pages, DRM_I915_GEM); obj->pages = NULL; @@ -2309,7 +2309,7 @@ i915_gem_release_mmap(struct drm_i915_gem_object * if (devobj != NULL) { page_count = OFF_TO_IDX(obj->base.size); - VM_OBJECT_LOCK(devobj); + VM_OBJECT_WLOCK(devobj); retry: for (i = 0; i < page_count; i++) { m = vm_page_lookup(devobj, i); @@ -2319,7 +2319,7 @@ retry: goto retry; cdev_pager_free_page(devobj, m); } - VM_OBJECT_UNLOCK(devobj); + VM_OBJECT_WUNLOCK(devobj); vm_object_deallocate(devobj); } @@ -2437,9 +2437,9 @@ i915_gem_object_truncate(struct drm_i915_gem_objec vm_object_t vm_obj; vm_obj = obj->base.vm_obj; - VM_OBJECT_LOCK(vm_obj); + VM_OBJECT_WLOCK(vm_obj); vm_object_page_remove(vm_obj, 0, 0, false); - VM_OBJECT_UNLOCK(vm_obj); + VM_OBJECT_WUNLOCK(vm_obj); obj->madv = I915_MADV_PURGED_INTERNAL; } @@ -2488,7 +2488,7 @@ i915_gem_wire_page(vm_object_t object, vm_pindex_t vm_page_t m; int rv; - VM_OBJECT_LOCK_ASSERT(object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(object, RA_WLOCKED); m = vm_page_grab(object, pindex, VM_ALLOC_NORMAL | VM_ALLOC_RETRY); if (m->valid != VM_PAGE_BITS_ALL) { if (vm_pager_has_page(object, pindex, NULL, NULL)) { @@ -3567,13 +3567,13 @@ i915_gem_detach_phys_object(struct drm_device *dev vaddr = obj->phys_obj->handle->vaddr; page_count = obj->base.size / PAGE_SIZE; - VM_OBJECT_LOCK(obj->base.vm_obj); + VM_OBJECT_WLOCK(obj->base.vm_obj); for (i = 0; i < page_count; i++) { m = i915_gem_wire_page(obj->base.vm_obj, i); if (m == NULL) continue; /* XXX */ - VM_OBJECT_UNLOCK(obj->base.vm_obj); + VM_OBJECT_WUNLOCK(obj->base.vm_obj); sf = sf_buf_alloc(m, 0); if (sf != NULL) { dst = (char *)sf_buf_kva(sf); @@ -3582,7 +3582,7 @@ i915_gem_detach_phys_object(struct drm_device *dev } drm_clflush_pages(&m, 1); - VM_OBJECT_LOCK(obj->base.vm_obj); + VM_OBJECT_WLOCK(obj->base.vm_obj); vm_page_reference(m); vm_page_lock(m); vm_page_dirty(m); @@ -3590,7 +3590,7 @@ i915_gem_detach_phys_object(struct drm_device *dev vm_page_unlock(m); atomic_add_long(&i915_gem_wired_pages_cnt, -1); } - VM_OBJECT_UNLOCK(obj->base.vm_obj); + VM_OBJECT_WUNLOCK(obj->base.vm_obj); intel_gtt_chipset_flush(); obj->phys_obj->cur_obj = NULL; @@ -3632,7 +3632,7 @@ i915_gem_attach_phys_object(struct drm_device *dev page_count = obj->base.size / PAGE_SIZE; - VM_OBJECT_LOCK(obj->base.vm_obj); + VM_OBJECT_WLOCK(obj->base.vm_obj); ret = 0; for (i = 0; i < page_count; i++) { m = i915_gem_wire_page(obj->base.vm_obj, i); @@ -3640,14 +3640,14 @@ i915_gem_attach_phys_object(struct drm_device *dev ret = -EIO; break; } - VM_OBJECT_UNLOCK(obj->base.vm_obj); + VM_OBJECT_WUNLOCK(obj->base.vm_obj); sf = sf_buf_alloc(m, 0); src = (char *)sf_buf_kva(sf); dst = (char *)obj->phys_obj->handle->vaddr + IDX_TO_OFF(i); memcpy(dst, src, PAGE_SIZE); sf_buf_free(sf); - VM_OBJECT_LOCK(obj->base.vm_obj); + VM_OBJECT_WLOCK(obj->base.vm_obj); vm_page_reference(m); vm_page_lock(m); @@ -3655,7 +3655,7 @@ i915_gem_attach_phys_object(struct drm_device *dev vm_page_unlock(m); atomic_add_long(&i915_gem_wired_pages_cnt, -1); } - VM_OBJECT_UNLOCK(obj->base.vm_obj); + VM_OBJECT_WUNLOCK(obj->base.vm_obj); return (0); } Index: dev/drm2/drmP.h =================================================================== --- dev/drm2/drmP.h (.../head/sys) (revision 247097) +++ dev/drm2/drmP.h (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -58,6 +58,7 @@ struct drm_file; #include #include #include +#include #include #include #include Index: conf/files =================================================================== --- conf/files (.../head/sys) (revision 247097) +++ conf/files (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -157,6 +157,7 @@ cddl/compat/opensolaris/kern/opensolaris_sysevent. cddl/compat/opensolaris/kern/opensolaris_taskq.c optional zfs compile-with "${ZFS_C}" cddl/compat/opensolaris/kern/opensolaris_uio.c optional zfs compile-with "${ZFS_C}" cddl/compat/opensolaris/kern/opensolaris_vfs.c optional zfs compile-with "${ZFS_C}" +cddl/compat/opensolaris/kern/opensolaris_vm.c optional zfs compile-with "${ZFS_C}" cddl/compat/opensolaris/kern/opensolaris_zone.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/common/acl/acl_common.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/common/avl/avl.c optional zfs compile-with "${ZFS_C}" Index: kern/vfs_bio.c =================================================================== --- kern/vfs_bio.c (.../head/sys) (revision 247097) +++ kern/vfs_bio.c (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -58,6 +58,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -458,7 +459,7 @@ vfs_buf_test_cache(struct buf *bp, vm_page_t m) { - VM_OBJECT_LOCK_ASSERT(m->object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(m->object, RA_WLOCKED); if (bp->b_flags & B_CACHE) { int base = (foff + off) & PAGE_MASK; if (vm_page_is_valid(m, base, size) == 0) @@ -1379,7 +1380,7 @@ brelse(struct buf *bp) */ resid = bp->b_bufsize; foff = bp->b_offset; - VM_OBJECT_LOCK(obj); + VM_OBJECT_WLOCK(obj); for (i = 0; i < bp->b_npages; i++) { int had_bogus = 0; @@ -1427,7 +1428,7 @@ brelse(struct buf *bp) resid -= PAGE_SIZE - (foff & PAGE_MASK); foff = (foff + PAGE_SIZE) & ~(off_t)PAGE_MASK; } - VM_OBJECT_UNLOCK(obj); + VM_OBJECT_WUNLOCK(obj); if (bp->b_flags & (B_INVAL | B_RELBUF)) vfs_vmio_release(bp); @@ -1655,7 +1656,7 @@ vfs_vmio_release(struct buf *bp) vm_page_t m; pmap_qremove(trunc_page((vm_offset_t)bp->b_data), bp->b_npages); - VM_OBJECT_LOCK(bp->b_bufobj->bo_object); + VM_OBJECT_WLOCK(bp->b_bufobj->bo_object); for (i = 0; i < bp->b_npages; i++) { m = bp->b_pages[i]; bp->b_pages[i] = NULL; @@ -1687,7 +1688,7 @@ vfs_vmio_release(struct buf *bp) } vm_page_unlock(m); } - VM_OBJECT_UNLOCK(bp->b_bufobj->bo_object); + VM_OBJECT_WUNLOCK(bp->b_bufobj->bo_object); if (bp->b_bufsize) { bufspacewakeup(); @@ -2464,7 +2465,7 @@ inmem(struct vnode * vp, daddr_t blkno) size = vp->v_mount->mnt_stat.f_iosize; off = (vm_ooffset_t)blkno * (vm_ooffset_t)vp->v_mount->mnt_stat.f_iosize; - VM_OBJECT_LOCK(obj); + VM_OBJECT_WLOCK(obj); for (toff = 0; toff < vp->v_mount->mnt_stat.f_iosize; toff += tinc) { m = vm_page_lookup(obj, OFF_TO_IDX(off + toff)); if (!m) @@ -2476,11 +2477,11 @@ inmem(struct vnode * vp, daddr_t blkno) (vm_offset_t) ((toff + off) & PAGE_MASK), tinc) == 0) goto notinmem; } - VM_OBJECT_UNLOCK(obj); + VM_OBJECT_WUNLOCK(obj); return 1; notinmem: - VM_OBJECT_UNLOCK(obj); + VM_OBJECT_WUNLOCK(obj); return (0); } @@ -2510,7 +2511,7 @@ vfs_clean_pages_dirty_buf(struct buf *bp) KASSERT(bp->b_offset != NOOFFSET, ("vfs_clean_pages_dirty_buf: no buffer offset")); - VM_OBJECT_LOCK(bp->b_bufobj->bo_object); + VM_OBJECT_WLOCK(bp->b_bufobj->bo_object); vfs_drain_busy_pages(bp); vfs_setdirty_locked_object(bp); for (i = 0; i < bp->b_npages; i++) { @@ -2523,7 +2524,7 @@ vfs_clean_pages_dirty_buf(struct buf *bp) /* vm_page_clear_dirty(m, foff & PAGE_MASK, eoff - foff); */ foff = noff; } - VM_OBJECT_UNLOCK(bp->b_bufobj->bo_object); + VM_OBJECT_WUNLOCK(bp->b_bufobj->bo_object); } static void @@ -2533,7 +2534,7 @@ vfs_setdirty_locked_object(struct buf *bp) int i; object = bp->b_bufobj->bo_object; - VM_OBJECT_LOCK_ASSERT(object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(object, RA_WLOCKED); /* * We qualify the scan for modified pages on whether the @@ -3035,7 +3036,7 @@ allocbuf(struct buf *bp, int size) (vm_offset_t)bp->b_data) + (desiredpages << PAGE_SHIFT), (bp->b_npages - desiredpages)); - VM_OBJECT_LOCK(bp->b_bufobj->bo_object); + VM_OBJECT_WLOCK(bp->b_bufobj->bo_object); for (i = desiredpages; i < bp->b_npages; i++) { /* * the page is not freed here -- it @@ -3054,7 +3055,7 @@ allocbuf(struct buf *bp, int size) vm_page_unwire(m, 0); vm_page_unlock(m); } - VM_OBJECT_UNLOCK(bp->b_bufobj->bo_object); + VM_OBJECT_WUNLOCK(bp->b_bufobj->bo_object); bp->b_npages = desiredpages; } } else if (size > bp->b_bcount) { @@ -3075,7 +3076,7 @@ allocbuf(struct buf *bp, int size) obj = bp->b_bufobj->bo_object; - VM_OBJECT_LOCK(obj); + VM_OBJECT_WLOCK(obj); while (bp->b_npages < desiredpages) { vm_page_t m; @@ -3137,7 +3138,7 @@ allocbuf(struct buf *bp, int size) toff += tinc; tinc = PAGE_SIZE; } - VM_OBJECT_UNLOCK(obj); + VM_OBJECT_WUNLOCK(obj); /* * Step 3, fixup the KVM pmap. Remember that @@ -3392,7 +3393,7 @@ bufdone_finish(struct buf *bp) bp->b_flags |= B_CACHE; } bogus = 0; - VM_OBJECT_LOCK(obj); + VM_OBJECT_WLOCK(obj); for (i = 0; i < bp->b_npages; i++) { int bogusflag = 0; int resid; @@ -3434,7 +3435,7 @@ bufdone_finish(struct buf *bp) iosize -= resid; } vm_object_pip_wakeupn(obj, 0); - VM_OBJECT_UNLOCK(obj); + VM_OBJECT_WUNLOCK(obj); if (bogus) pmap_qenter(trunc_page((vm_offset_t)bp->b_data), bp->b_pages, bp->b_npages); @@ -3472,7 +3473,7 @@ vfs_unbusy_pages(struct buf *bp) return; obj = bp->b_bufobj->bo_object; - VM_OBJECT_LOCK(obj); + VM_OBJECT_WLOCK(obj); for (i = 0; i < bp->b_npages; i++) { m = bp->b_pages[i]; if (m == bogus_page) { @@ -3487,7 +3488,7 @@ vfs_unbusy_pages(struct buf *bp) vm_page_io_finish(m); } vm_object_pip_wakeupn(obj, 0); - VM_OBJECT_UNLOCK(obj); + VM_OBJECT_WUNLOCK(obj); } /* @@ -3566,7 +3567,7 @@ vfs_drain_busy_pages(struct buf *bp) vm_page_t m; int i, last_busied; - VM_OBJECT_LOCK_ASSERT(bp->b_bufobj->bo_object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(bp->b_bufobj->bo_object, RA_WLOCKED); last_busied = 0; for (i = 0; i < bp->b_npages; i++) { m = bp->b_pages[i]; @@ -3608,7 +3609,7 @@ vfs_busy_pages(struct buf *bp, int clear_modify) foff = bp->b_offset; KASSERT(bp->b_offset != NOOFFSET, ("vfs_busy_pages: no buffer offset")); - VM_OBJECT_LOCK(obj); + VM_OBJECT_WLOCK(obj); vfs_drain_busy_pages(bp); if (bp->b_bufsize != 0) vfs_setdirty_locked_object(bp); @@ -3645,7 +3646,7 @@ vfs_busy_pages(struct buf *bp, int clear_modify) } foff = (foff + PAGE_SIZE) & ~(off_t)PAGE_MASK; } - VM_OBJECT_UNLOCK(obj); + VM_OBJECT_WUNLOCK(obj); if (bogus) pmap_qenter(trunc_page((vm_offset_t)bp->b_data), bp->b_pages, bp->b_npages); @@ -3676,7 +3677,7 @@ vfs_bio_set_valid(struct buf *bp, int base, int si base += (bp->b_offset & PAGE_MASK); n = PAGE_SIZE - (base & PAGE_MASK); - VM_OBJECT_LOCK(bp->b_bufobj->bo_object); + VM_OBJECT_WLOCK(bp->b_bufobj->bo_object); for (i = base / PAGE_SIZE; size > 0 && i < bp->b_npages; ++i) { m = bp->b_pages[i]; if (n > size) @@ -3686,7 +3687,7 @@ vfs_bio_set_valid(struct buf *bp, int base, int si size -= n; n = PAGE_SIZE; } - VM_OBJECT_UNLOCK(bp->b_bufobj->bo_object); + VM_OBJECT_WUNLOCK(bp->b_bufobj->bo_object); } /* @@ -3713,13 +3714,13 @@ vfs_bio_clrbuf(struct buf *bp) } bp->b_flags &= ~B_INVAL; bp->b_ioflags &= ~BIO_ERROR; - VM_OBJECT_LOCK(bp->b_bufobj->bo_object); + VM_OBJECT_WLOCK(bp->b_bufobj->bo_object); if ((bp->b_npages == 1) && (bp->b_bufsize < PAGE_SIZE) && (bp->b_offset & PAGE_MASK) == 0) { if (bp->b_pages[0] == bogus_page) goto unlock; mask = (1 << (bp->b_bufsize / DEV_BSIZE)) - 1; - VM_OBJECT_LOCK_ASSERT(bp->b_pages[0]->object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(bp->b_pages[0]->object, RA_WLOCKED); if ((bp->b_pages[0]->valid & mask) == mask) goto unlock; if ((bp->b_pages[0]->valid & mask) == 0) { @@ -3738,7 +3739,7 @@ vfs_bio_clrbuf(struct buf *bp) continue; j = ((vm_offset_t)sa & PAGE_MASK) / DEV_BSIZE; mask = ((1 << ((ea - sa) / DEV_BSIZE)) - 1) << j; - VM_OBJECT_LOCK_ASSERT(bp->b_pages[i]->object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(bp->b_pages[i]->object, RA_WLOCKED); if ((bp->b_pages[i]->valid & mask) == mask) continue; if ((bp->b_pages[i]->valid & mask) == 0) @@ -3752,7 +3753,7 @@ vfs_bio_clrbuf(struct buf *bp) bp->b_pages[i]->valid |= mask; } unlock: - VM_OBJECT_UNLOCK(bp->b_bufobj->bo_object); + VM_OBJECT_WUNLOCK(bp->b_bufobj->bo_object); bp->b_resid = 0; } Index: kern/vfs_default.c =================================================================== --- kern/vfs_default.c (.../head/sys) (revision 247097) +++ kern/vfs_default.c (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -47,8 +47,8 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include +#include #include #include #include @@ -1043,10 +1043,10 @@ vop_stdadvise(struct vop_advise_args *ap) if (vp->v_object != NULL) { start = trunc_page(ap->a_start); end = round_page(ap->a_end); - VM_OBJECT_LOCK(vp->v_object); + VM_OBJECT_WLOCK(vp->v_object); vm_object_page_cache(vp->v_object, OFF_TO_IDX(start), OFF_TO_IDX(end)); - VM_OBJECT_UNLOCK(vp->v_object); + VM_OBJECT_WUNLOCK(vp->v_object); } VOP_UNLOCK(vp, 0); break; Index: kern/kern_proc.c =================================================================== --- kern/kern_proc.c (.../head/sys) (revision 247097) +++ kern/kern_proc.c (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -55,6 +55,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -1994,7 +1995,7 @@ sysctl_kern_proc_ovmmap(SYSCTL_HANDLER_ARGS) kve->kve_private_resident = 0; obj = entry->object.vm_object; if (obj != NULL) { - VM_OBJECT_LOCK(obj); + VM_OBJECT_WLOCK(obj); if (obj->shadow_count == 1) kve->kve_private_resident = obj->resident_page_count; @@ -2009,9 +2010,9 @@ sysctl_kern_proc_ovmmap(SYSCTL_HANDLER_ARGS) for (lobj = tobj = obj; tobj; tobj = tobj->backing_object) { if (tobj != obj) - VM_OBJECT_LOCK(tobj); + VM_OBJECT_WLOCK(tobj); if (lobj != obj) - VM_OBJECT_UNLOCK(lobj); + VM_OBJECT_WUNLOCK(lobj); lobj = tobj; } @@ -2071,11 +2072,11 @@ sysctl_kern_proc_ovmmap(SYSCTL_HANDLER_ARGS) break; } if (lobj != obj) - VM_OBJECT_UNLOCK(lobj); + VM_OBJECT_WUNLOCK(lobj); kve->kve_ref_count = obj->ref_count; kve->kve_shadow_count = obj->shadow_count; - VM_OBJECT_UNLOCK(obj); + VM_OBJECT_WUNLOCK(obj); if (vp != NULL) { vn_fullpath(curthread, vp, &fullpath, &freepath); @@ -2161,7 +2162,7 @@ sysctl_kern_proc_vmmap(SYSCTL_HANDLER_ARGS) kve->kve_private_resident = 0; obj = entry->object.vm_object; if (obj != NULL) { - VM_OBJECT_LOCK(obj); + VM_OBJECT_WLOCK(obj); if (obj->shadow_count == 1) kve->kve_private_resident = obj->resident_page_count; @@ -2182,9 +2183,9 @@ sysctl_kern_proc_vmmap(SYSCTL_HANDLER_ARGS) for (lobj = tobj = obj; tobj; tobj = tobj->backing_object) { if (tobj != obj) - VM_OBJECT_LOCK(tobj); + VM_OBJECT_WLOCK(tobj); if (lobj != obj) - VM_OBJECT_UNLOCK(lobj); + VM_OBJECT_WUNLOCK(lobj); lobj = tobj; } @@ -2246,11 +2247,11 @@ sysctl_kern_proc_vmmap(SYSCTL_HANDLER_ARGS) break; } if (lobj != obj) - VM_OBJECT_UNLOCK(lobj); + VM_OBJECT_WUNLOCK(lobj); kve->kve_ref_count = obj->ref_count; kve->kve_shadow_count = obj->shadow_count; - VM_OBJECT_UNLOCK(obj); + VM_OBJECT_WUNLOCK(obj); if (vp != NULL) { vn_fullpath(curthread, vp, &fullpath, &freepath); Index: kern/subr_uio.c =================================================================== --- kern/subr_uio.c (.../head/sys) (revision 247097) +++ kern/subr_uio.c (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -45,9 +45,9 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include #include +#include #include #include #include @@ -104,7 +104,7 @@ vm_pgmoveco(vm_map_t mapa, vm_offset_t kaddr, vm_o &upindex, &prot, &wired)) != KERN_SUCCESS) { return(EFAULT); } - VM_OBJECT_LOCK(uobject); + VM_OBJECT_WLOCK(uobject); retry: if ((user_pg = vm_page_lookup(uobject, upindex)) != NULL) { if (vm_page_sleep_if_busy(user_pg, TRUE, "vm_pgmoveco")) @@ -124,7 +124,7 @@ retry: } vm_page_insert(kern_pg, uobject, upindex); vm_page_dirty(kern_pg); - VM_OBJECT_UNLOCK(uobject); + VM_OBJECT_WUNLOCK(uobject); vm_map_lookup_done(map, entry); return(KERN_SUCCESS); } Index: kern/imgact_elf.c =================================================================== --- kern/imgact_elf.c (.../head/sys) (revision 247097) +++ kern/imgact_elf.c (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -45,7 +45,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include #include #include @@ -53,6 +52,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -1278,15 +1278,15 @@ each_writable_segment(td, func, closure) continue; /* Ignore memory-mapped devices and such things. */ - VM_OBJECT_LOCK(object); + VM_OBJECT_WLOCK(object); while ((backing_object = object->backing_object) != NULL) { - VM_OBJECT_LOCK(backing_object); - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WLOCK(backing_object); + VM_OBJECT_WUNLOCK(object); object = backing_object; } ignore_entry = object->type != OBJT_DEFAULT && object->type != OBJT_SWAP && object->type != OBJT_VNODE; - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); if (ignore_entry) continue; Index: kern/vfs_cluster.c =================================================================== --- kern/vfs_cluster.c (.../head/sys) (revision 247097) +++ kern/vfs_cluster.c (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -46,6 +46,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -406,21 +407,21 @@ cluster_rbuild(vp, filesize, lbn, blkno, size, run */ off = tbp->b_offset; tsize = size; - VM_OBJECT_LOCK(tbp->b_bufobj->bo_object); + VM_OBJECT_WLOCK(tbp->b_bufobj->bo_object); for (j = 0; tsize > 0; j++) { toff = off & PAGE_MASK; tinc = tsize; if (toff + tinc > PAGE_SIZE) tinc = PAGE_SIZE - toff; VM_OBJECT_LOCK_ASSERT(tbp->b_pages[j]->object, - MA_OWNED); + RA_WLOCKED); if ((tbp->b_pages[j]->valid & vm_page_bits(toff, tinc)) != 0) break; off += tinc; tsize -= tinc; } - VM_OBJECT_UNLOCK(tbp->b_bufobj->bo_object); + VM_OBJECT_WUNLOCK(tbp->b_bufobj->bo_object); if (tsize > 0) { bqrelse(tbp); break; @@ -455,7 +456,7 @@ cluster_rbuild(vp, filesize, lbn, blkno, size, run BUF_KERNPROC(tbp); TAILQ_INSERT_TAIL(&bp->b_cluster.cluster_head, tbp, b_cluster.cluster_entry); - VM_OBJECT_LOCK(tbp->b_bufobj->bo_object); + VM_OBJECT_WLOCK(tbp->b_bufobj->bo_object); for (j = 0; j < tbp->b_npages; j += 1) { vm_page_t m; m = tbp->b_pages[j]; @@ -469,7 +470,7 @@ cluster_rbuild(vp, filesize, lbn, blkno, size, run if (m->valid == VM_PAGE_BITS_ALL) tbp->b_pages[j] = bogus_page; } - VM_OBJECT_UNLOCK(tbp->b_bufobj->bo_object); + VM_OBJECT_WUNLOCK(tbp->b_bufobj->bo_object); /* * Don't inherit tbp->b_bufsize as it may be larger due to * a non-page-aligned size. Instead just aggregate using @@ -487,13 +488,13 @@ cluster_rbuild(vp, filesize, lbn, blkno, size, run * Fully valid pages in the cluster are already good and do not need * to be re-read from disk. Replace the page with bogus_page */ - VM_OBJECT_LOCK(bp->b_bufobj->bo_object); + VM_OBJECT_WLOCK(bp->b_bufobj->bo_object); for (j = 0; j < bp->b_npages; j++) { - VM_OBJECT_LOCK_ASSERT(bp->b_pages[j]->object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(bp->b_pages[j]->object, RA_WLOCKED); if (bp->b_pages[j]->valid == VM_PAGE_BITS_ALL) bp->b_pages[j] = bogus_page; } - VM_OBJECT_UNLOCK(bp->b_bufobj->bo_object); + VM_OBJECT_WUNLOCK(bp->b_bufobj->bo_object); if (bp->b_bufsize > bp->b_kvasize) panic("cluster_rbuild: b_bufsize(%ld) > b_kvasize(%d)\n", bp->b_bufsize, bp->b_kvasize); @@ -918,12 +919,12 @@ cluster_wbuild(vp, size, start_lbn, len) if (tbp->b_flags & B_VMIO) { vm_page_t m; - VM_OBJECT_LOCK(tbp->b_bufobj->bo_object); + VM_OBJECT_WLOCK(tbp->b_bufobj->bo_object); if (i != 0) { /* if not first buffer */ for (j = 0; j < tbp->b_npages; j += 1) { m = tbp->b_pages[j]; if (m->oflags & VPO_BUSY) { - VM_OBJECT_UNLOCK( + VM_OBJECT_WUNLOCK( tbp->b_object); bqrelse(tbp); goto finishcluster; @@ -940,7 +941,7 @@ cluster_wbuild(vp, size, start_lbn, len) bp->b_npages++; } } - VM_OBJECT_UNLOCK(tbp->b_bufobj->bo_object); + VM_OBJECT_WUNLOCK(tbp->b_bufobj->bo_object); } bp->b_bcount += size; bp->b_bufsize += size; Index: kern/sysv_shm.c =================================================================== --- kern/sysv_shm.c (.../head/sys) (revision 247097) +++ kern/sysv_shm.c (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -79,6 +79,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -707,10 +708,10 @@ shmget_allocate_segment(td, uap, mode) #endif return (ENOMEM); } - VM_OBJECT_LOCK(shm_object); + VM_OBJECT_WLOCK(shm_object); vm_object_clear_flag(shm_object, OBJ_ONEMAPPING); vm_object_set_flag(shm_object, OBJ_NOSPLIT); - VM_OBJECT_UNLOCK(shm_object); + VM_OBJECT_WUNLOCK(shm_object); shmseg->object = shm_object; shmseg->u.shm_perm.cuid = shmseg->u.shm_perm.uid = cred->cr_uid; Index: kern/kern_sharedpage.c =================================================================== --- kern/kern_sharedpage.c (.../head/sys) (revision 247097) +++ kern/kern_sharedpage.c (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -34,7 +34,7 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include +#include #include #include #include @@ -107,11 +107,11 @@ shared_page_init(void *dummy __unused) sx_init(&shared_page_alloc_sx, "shpsx"); shared_page_obj = vm_pager_allocate(OBJT_PHYS, 0, PAGE_SIZE, VM_PROT_DEFAULT, 0, NULL); - VM_OBJECT_LOCK(shared_page_obj); + VM_OBJECT_WLOCK(shared_page_obj); m = vm_page_grab(shared_page_obj, 0, VM_ALLOC_RETRY | VM_ALLOC_NOBUSY | VM_ALLOC_ZERO); m->valid = VM_PAGE_BITS_ALL; - VM_OBJECT_UNLOCK(shared_page_obj); + VM_OBJECT_WUNLOCK(shared_page_obj); addr = kmem_alloc_nofault(kernel_map, PAGE_SIZE); pmap_qenter(addr, &m, 1); shared_page_mapping = (char *)addr; Index: kern/kern_exec.c =================================================================== --- kern/kern_exec.c (.../head/sys) (revision 247097) +++ kern/kern_exec.c (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -57,6 +57,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -932,7 +933,7 @@ exec_map_first_page(imgp) object = imgp->vp->v_object; if (object == NULL) return (EACCES); - VM_OBJECT_LOCK(object); + VM_OBJECT_WLOCK(object); #if VM_NRESERVLEVEL > 0 if ((object->flags & OBJ_COLORED) == 0) { object->flags |= OBJ_COLORED; @@ -967,7 +968,7 @@ exec_map_first_page(imgp) vm_page_free(ma[0]); vm_page_unlock(ma[0]); } - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); return (EIO); } } @@ -975,7 +976,7 @@ exec_map_first_page(imgp) vm_page_hold(ma[0]); vm_page_unlock(ma[0]); vm_page_wakeup(ma[0]); - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); imgp->firstpage = sf_buf_alloc(ma[0], 0); imgp->image_header = (char *)sf_buf_kva(imgp->firstpage); Index: kern/uipc_shm.c =================================================================== --- kern/uipc_shm.c (.../head/sys) (revision 247097) +++ kern/uipc_shm.c (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -61,6 +61,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -253,9 +254,9 @@ shm_dotruncate(struct shmfd *shmfd, off_t length) int base, rv; object = shmfd->shm_object; - VM_OBJECT_LOCK(object); + VM_OBJECT_WLOCK(object); if (length == shmfd->shm_size) { - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); return (0); } nobjsize = OFF_TO_IDX(length + PAGE_MASK); @@ -267,7 +268,7 @@ shm_dotruncate(struct shmfd *shmfd, off_t length) * object is mapped into the kernel. */ if (shmfd->shm_kmappings > 0) { - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); return (EBUSY); } @@ -288,9 +289,9 @@ retry: } else if (vm_pager_has_page(object, idx, NULL, NULL)) { m = vm_page_alloc(object, idx, VM_ALLOC_NORMAL); if (m == NULL) { - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); VM_WAIT; - VM_OBJECT_LOCK(object); + VM_OBJECT_WLOCK(object); goto retry; } else if (m->valid != VM_PAGE_BITS_ALL) { ma[0] = m; @@ -308,7 +309,7 @@ retry: } else { vm_page_free(m); vm_page_unlock(m); - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); return (EIO); } } @@ -338,7 +339,7 @@ retry: /* Attempt to reserve the swap */ delta = ptoa(nobjsize - object->size); if (!swap_reserve_by_cred(delta, object->cred)) { - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); return (ENOMEM); } object->charge += delta; @@ -349,7 +350,7 @@ retry: shmfd->shm_mtime = shmfd->shm_ctime; mtx_unlock(&shm_timestamp_lock); object->size = nobjsize; - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); return (0); } @@ -370,10 +371,10 @@ shm_alloc(struct ucred *ucred, mode_t mode) shmfd->shm_object = vm_pager_allocate(OBJT_DEFAULT, NULL, shmfd->shm_size, VM_PROT_DEFAULT, 0, ucred); KASSERT(shmfd->shm_object != NULL, ("shm_create: vm_pager_allocate")); - VM_OBJECT_LOCK(shmfd->shm_object); + VM_OBJECT_WLOCK(shmfd->shm_object); vm_object_clear_flag(shmfd->shm_object, OBJ_ONEMAPPING); vm_object_set_flag(shmfd->shm_object, OBJ_NOSPLIT); - VM_OBJECT_UNLOCK(shmfd->shm_object); + VM_OBJECT_WUNLOCK(shmfd->shm_object); vfs_timestamp(&shmfd->shm_birthtime); shmfd->shm_atime = shmfd->shm_mtime = shmfd->shm_ctime = shmfd->shm_birthtime; @@ -761,20 +762,20 @@ shm_map(struct file *fp, size_t size, off_t offset return (EINVAL); shmfd = fp->f_data; obj = shmfd->shm_object; - VM_OBJECT_LOCK(obj); + VM_OBJECT_WLOCK(obj); /* * XXXRW: This validation is probably insufficient, and subject to * sign errors. It should be fixed. */ if (offset >= shmfd->shm_size || offset + size > round_page(shmfd->shm_size)) { - VM_OBJECT_UNLOCK(obj); + VM_OBJECT_WUNLOCK(obj); return (EINVAL); } shmfd->shm_kmappings++; vm_object_reference_locked(obj); - VM_OBJECT_UNLOCK(obj); + VM_OBJECT_WUNLOCK(obj); /* Map the object into the kernel_map and wire it. */ kva = vm_map_min(kernel_map); @@ -796,9 +797,9 @@ shm_map(struct file *fp, size_t size, off_t offset vm_object_deallocate(obj); /* On failure, drop our mapping reference. */ - VM_OBJECT_LOCK(obj); + VM_OBJECT_WLOCK(obj); shmfd->shm_kmappings--; - VM_OBJECT_UNLOCK(obj); + VM_OBJECT_WUNLOCK(obj); return (vm_mmap_to_errno(rv)); } @@ -840,10 +841,10 @@ shm_unmap(struct file *fp, void *mem, size_t size) if (obj != shmfd->shm_object) return (EINVAL); vm_map_remove(map, kva, kva + size); - VM_OBJECT_LOCK(obj); + VM_OBJECT_WLOCK(obj); KASSERT(shmfd->shm_kmappings > 0, ("shm_unmap: object not mapped")); shmfd->shm_kmappings--; - VM_OBJECT_UNLOCK(obj); + VM_OBJECT_WUNLOCK(obj); return (0); } Index: kern/vfs_aio.c =================================================================== --- kern/vfs_aio.c (.../head/sys) (revision 247097) +++ kern/vfs_aio.c (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -46,6 +46,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -841,9 +842,9 @@ aio_fsync_vnode(struct thread *td, struct vnode *v goto drop; vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); if (vp->v_object != NULL) { - VM_OBJECT_LOCK(vp->v_object); + VM_OBJECT_WLOCK(vp->v_object); vm_object_page_clean(vp->v_object, 0, 0, 0); - VM_OBJECT_UNLOCK(vp->v_object); + VM_OBJECT_WUNLOCK(vp->v_object); } error = VOP_FSYNC(vp, MNT_WAIT, td); Index: kern/sys_process.c =================================================================== --- kern/sys_process.c (.../head/sys) (revision 247097) +++ kern/sys_process.c (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -44,6 +44,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -59,7 +60,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include #ifdef COMPAT_FREEBSD32 @@ -382,7 +382,7 @@ ptrace_vm_entry(struct thread *td, struct proc *p, obj = entry->object.vm_object; if (obj != NULL) - VM_OBJECT_LOCK(obj); + VM_OBJECT_WLOCK(obj); } while (0); vm_map_unlock_read(map); @@ -395,9 +395,9 @@ ptrace_vm_entry(struct thread *td, struct proc *p, lobj = obj; for (tobj = obj; tobj != NULL; tobj = tobj->backing_object) { if (tobj != obj) - VM_OBJECT_LOCK(tobj); + VM_OBJECT_WLOCK(tobj); if (lobj != obj) - VM_OBJECT_UNLOCK(lobj); + VM_OBJECT_WUNLOCK(lobj); lobj = tobj; pve->pve_offset += tobj->backing_object_offset; } @@ -405,8 +405,8 @@ ptrace_vm_entry(struct thread *td, struct proc *p, if (vp != NULL) vref(vp); if (lobj != obj) - VM_OBJECT_UNLOCK(lobj); - VM_OBJECT_UNLOCK(obj); + VM_OBJECT_WUNLOCK(lobj); + VM_OBJECT_WUNLOCK(obj); if (vp != NULL) { freepath = NULL; Index: kern/vfs_subr.c =================================================================== --- kern/vfs_subr.c (.../head/sys) (revision 247097) +++ kern/vfs_subr.c (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -67,6 +67,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -1244,9 +1245,9 @@ bufobj_invalbuf(struct bufobj *bo, int flags, int bufobj_wwait(bo, 0, 0); BO_UNLOCK(bo); if (bo->bo_object != NULL) { - VM_OBJECT_LOCK(bo->bo_object); + VM_OBJECT_WLOCK(bo->bo_object); vm_object_pip_wait(bo->bo_object, "bovlbx"); - VM_OBJECT_UNLOCK(bo->bo_object); + VM_OBJECT_WUNLOCK(bo->bo_object); } BO_LOCK(bo); } while (bo->bo_numoutput > 0); @@ -1257,10 +1258,10 @@ bufobj_invalbuf(struct bufobj *bo, int flags, int */ if (bo->bo_object != NULL && (flags & (V_ALT | V_NORMAL | V_CLEANONLY)) == 0) { - VM_OBJECT_LOCK(bo->bo_object); + VM_OBJECT_WLOCK(bo->bo_object); vm_object_page_remove(bo->bo_object, 0, 0, (flags & V_SAVE) ? OBJPR_CLEANONLY : 0); - VM_OBJECT_UNLOCK(bo->bo_object); + VM_OBJECT_WUNLOCK(bo->bo_object); } #ifdef INVARIANTS @@ -2520,9 +2521,9 @@ vinactive(struct vnode *vp, struct thread *td) */ obj = vp->v_object; if (obj != NULL && (obj->flags & OBJ_MIGHTBEDIRTY) != 0) { - VM_OBJECT_LOCK(obj); + VM_OBJECT_WLOCK(obj); vm_object_page_clean(obj, 0, 0, OBJPC_NOSYNC); - VM_OBJECT_UNLOCK(obj); + VM_OBJECT_WUNLOCK(obj); } VOP_INACTIVE(vp, td); VI_LOCK(vp); @@ -2603,9 +2604,9 @@ loop: */ if (flags & WRITECLOSE) { if (vp->v_object != NULL) { - VM_OBJECT_LOCK(vp->v_object); + VM_OBJECT_WLOCK(vp->v_object); vm_object_page_clean(vp->v_object, 0, 0, 0); - VM_OBJECT_UNLOCK(vp->v_object); + VM_OBJECT_WUNLOCK(vp->v_object); } error = VOP_FSYNC(vp, MNT_WAIT, td); if (error != 0) { @@ -3503,11 +3504,11 @@ vfs_msync(struct mount *mp, int flags) obj = vp->v_object; if (obj != NULL) { - VM_OBJECT_LOCK(obj); + VM_OBJECT_WLOCK(obj); vm_object_page_clean(obj, 0, 0, flags == MNT_WAIT ? OBJPC_SYNC : OBJPC_NOSYNC); - VM_OBJECT_UNLOCK(obj); + VM_OBJECT_WUNLOCK(obj); } vput(vp); } Index: kern/vfs_vnops.c =================================================================== --- kern/vfs_vnops.c (.../head/sys) (revision 247097) +++ kern/vfs_vnops.c (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -55,6 +55,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -1896,9 +1897,9 @@ vn_pages_remove(struct vnode *vp, vm_pindex_t star if ((object = vp->v_object) == NULL) return; - VM_OBJECT_LOCK(object); + VM_OBJECT_WLOCK(object); vm_object_page_remove(object, start, end, 0); - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); } int Index: kern/kern_shutdown.c =================================================================== --- kern/kern_shutdown.c (.../head/sys) (revision 247097) +++ kern/kern_shutdown.c (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -62,6 +62,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include Index: kern/vfs_syscalls.c =================================================================== --- kern/vfs_syscalls.c (.../head/sys) (revision 247097) +++ kern/vfs_syscalls.c (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -61,6 +61,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -3432,9 +3433,9 @@ sys_fsync(td, uap) vn_lock(vp, lock_flags | LK_RETRY); AUDIT_ARG_VNODE1(vp); if (vp->v_object != NULL) { - VM_OBJECT_LOCK(vp->v_object); + VM_OBJECT_WLOCK(vp->v_object); vm_object_page_clean(vp->v_object, 0, 0, 0); - VM_OBJECT_UNLOCK(vp->v_object); + VM_OBJECT_WUNLOCK(vp->v_object); } error = VOP_FSYNC(vp, MNT_WAIT, td); Index: kern/uipc_syscalls.c =================================================================== --- kern/uipc_syscalls.c (.../head/sys) (revision 247097) +++ kern/uipc_syscalls.c (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -60,6 +60,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -1862,12 +1863,12 @@ kern_sendfile(struct thread *td, struct sendfile_a * reclamation of its vnode does not * immediately destroy it. */ - VM_OBJECT_LOCK(obj); + VM_OBJECT_WLOCK(obj); if ((obj->flags & OBJ_DEAD) == 0) { vm_object_reference_locked(obj); - VM_OBJECT_UNLOCK(obj); + VM_OBJECT_WUNLOCK(obj); } else { - VM_OBJECT_UNLOCK(obj); + VM_OBJECT_WUNLOCK(obj); obj = NULL; } } @@ -2044,7 +2045,7 @@ retry_space: vm_offset_t pgoff; struct mbuf *m0; - VM_OBJECT_LOCK(obj); + VM_OBJECT_WLOCK(obj); /* * Calculate the amount to transfer. * Not to exceed a page, the EOF, @@ -2062,7 +2063,7 @@ retry_space: xfsize = omin(rem, xfsize); xfsize = omin(space - loopbytes, xfsize); if (xfsize <= 0) { - VM_OBJECT_UNLOCK(obj); + VM_OBJECT_WUNLOCK(obj); done = 1; /* all data sent */ break; } @@ -2083,7 +2084,7 @@ retry_space: * block. */ if (pg->valid && vm_page_is_valid(pg, pgoff, xfsize)) - VM_OBJECT_UNLOCK(obj); + VM_OBJECT_WUNLOCK(obj); else if (m != NULL) error = EAGAIN; /* send what we already got */ else if (uap->flags & SF_NODISKIO) @@ -2097,7 +2098,7 @@ retry_space: * when the I/O completes. */ vm_page_io_start(pg); - VM_OBJECT_UNLOCK(obj); + VM_OBJECT_WUNLOCK(obj); /* * Get the page from backing store. @@ -2119,10 +2120,10 @@ retry_space: td->td_ucred, NOCRED, &resid, td); VOP_UNLOCK(vp, 0); after_read: - VM_OBJECT_LOCK(obj); + VM_OBJECT_WLOCK(obj); vm_page_io_finish(pg); if (!error) - VM_OBJECT_UNLOCK(obj); + VM_OBJECT_WUNLOCK(obj); mbstat.sf_iocnt++; } if (error) { @@ -2137,7 +2138,7 @@ retry_space: pg->busy == 0 && !(pg->oflags & VPO_BUSY)) vm_page_free(pg); vm_page_unlock(pg); - VM_OBJECT_UNLOCK(obj); + VM_OBJECT_WUNLOCK(obj); if (error == EAGAIN) error = 0; /* not a real error */ break; Index: boot =================================================================== --- boot (.../head/sys) (revision 247097) +++ boot (.../user/attilio/vmobj-rwlock/sys) (revision 247097) Property changes on: boot ___________________________________________________________________ Modified: svn:mergeinfo Merged /head/sys/boot:r247016-247096 Index: ia64/ia64/pmap.c =================================================================== --- ia64/ia64/pmap.c (.../head/sys) (revision 247097) +++ ia64/ia64/pmap.c (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -1802,7 +1802,7 @@ pmap_enter_object(pmap_t pmap, vm_offset_t start, vm_page_t m; vm_pindex_t diff, psize; - VM_OBJECT_LOCK_ASSERT(m_start->object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(m_start->object, RA_WLOCKED); psize = atop(end - start); m = m_start; rw_wlock(&pvh_global_lock); @@ -1893,7 +1893,7 @@ pmap_object_init_pt(pmap_t pmap, vm_offset_t addr, vm_size_t size) { - VM_OBJECT_LOCK_ASSERT(object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(object, RA_WLOCKED); KASSERT(object->type == OBJT_DEVICE || object->type == OBJT_SG, ("pmap_object_init_pt: non-device object")); } @@ -2211,7 +2211,7 @@ pmap_is_modified(vm_page_t m) * concurrently set while the object is locked. Thus, if PGA_WRITEABLE * is clear, no PTEs can be dirty. */ - VM_OBJECT_LOCK_ASSERT(m->object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(m->object, RA_WLOCKED); if ((m->oflags & VPO_BUSY) == 0 && (m->aflags & PGA_WRITEABLE) == 0) return (rv); @@ -2295,7 +2295,7 @@ pmap_clear_modify(vm_page_t m) KASSERT((m->oflags & VPO_UNMANAGED) == 0, ("pmap_clear_modify: page %p is not managed", m)); - VM_OBJECT_LOCK_ASSERT(m->object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(m->object, RA_WLOCKED); KASSERT((m->oflags & VPO_BUSY) == 0, ("pmap_clear_modify: page %p is busy", m)); @@ -2373,7 +2373,7 @@ pmap_remove_write(vm_page_t m) * another thread while the object is locked. Thus, if PGA_WRITEABLE * is clear, no page table entries need updating. */ - VM_OBJECT_LOCK_ASSERT(m->object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(m->object, RA_WLOCKED); if ((m->oflags & VPO_BUSY) == 0 && (m->aflags & PGA_WRITEABLE) == 0) return; Index: ia64/ia64/machdep.c =================================================================== --- ia64/ia64/machdep.c (.../head/sys) (revision 247097) +++ ia64/ia64/machdep.c (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -55,6 +55,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include Index: fs/nfsclient/nfs_clvnops.c =================================================================== --- fs/nfsclient/nfs_clvnops.c (.../head/sys) (revision 247097) +++ fs/nfsclient/nfs_clvnops.c (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -697,9 +697,9 @@ nfs_close(struct vop_close_args *ap) * mmap'ed writes or via write(). */ if (nfs_clean_pages_on_close && vp->v_object) { - VM_OBJECT_LOCK(vp->v_object); + VM_OBJECT_WLOCK(vp->v_object); vm_object_page_clean(vp->v_object, 0, 0, 0); - VM_OBJECT_UNLOCK(vp->v_object); + VM_OBJECT_WUNLOCK(vp->v_object); } mtx_lock(&np->n_mtx); if (np->n_flag & NMODIFIED) { Index: fs/nfsclient/nfs_clbio.c =================================================================== --- fs/nfsclient/nfs_clbio.c (.../head/sys) (revision 247097) +++ fs/nfsclient/nfs_clbio.c (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -43,6 +43,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -134,7 +135,7 @@ ncl_getpages(struct vop_getpages_args *ap) * allow the pager to zero-out the blanks. Partially valid pages * can only occur at the file EOF. */ - VM_OBJECT_LOCK(object); + VM_OBJECT_WLOCK(object); if (pages[ap->a_reqpage]->valid != 0) { for (i = 0; i < npages; ++i) { if (i != ap->a_reqpage) { @@ -143,10 +144,10 @@ ncl_getpages(struct vop_getpages_args *ap) vm_page_unlock(pages[i]); } } - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); return (0); } - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); /* * We use only the kva address for the buffer, but this is extremely @@ -176,7 +177,7 @@ ncl_getpages(struct vop_getpages_args *ap) if (error && (uio.uio_resid == count)) { ncl_printf("nfs_getpages: error %d\n", error); - VM_OBJECT_LOCK(object); + VM_OBJECT_WLOCK(object); for (i = 0; i < npages; ++i) { if (i != ap->a_reqpage) { vm_page_lock(pages[i]); @@ -184,7 +185,7 @@ ncl_getpages(struct vop_getpages_args *ap) vm_page_unlock(pages[i]); } } - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); return (VM_PAGER_ERROR); } @@ -195,7 +196,7 @@ ncl_getpages(struct vop_getpages_args *ap) */ size = count - uio.uio_resid; - VM_OBJECT_LOCK(object); + VM_OBJECT_WLOCK(object); for (i = 0, toff = 0; i < npages; i++, toff = nextoff) { vm_page_t m; nextoff = toff + PAGE_SIZE; @@ -231,7 +232,7 @@ ncl_getpages(struct vop_getpages_args *ap) if (i != ap->a_reqpage) vm_page_readahead_finish(m); } - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); return (0); } @@ -1353,9 +1354,9 @@ ncl_vinvalbuf(struct vnode *vp, int flags, struct * Now, flush as required. */ if ((flags & V_SAVE) && (vp->v_bufobj.bo_object != NULL)) { - VM_OBJECT_LOCK(vp->v_bufobj.bo_object); + VM_OBJECT_WLOCK(vp->v_bufobj.bo_object); vm_object_page_clean(vp->v_bufobj.bo_object, 0, 0, OBJPC_SYNC); - VM_OBJECT_UNLOCK(vp->v_bufobj.bo_object); + VM_OBJECT_WUNLOCK(vp->v_bufobj.bo_object); /* * If the page clean was interrupted, fail the invalidation. * Not doing so, we run the risk of losing dirty pages in the Index: fs/nfsclient/nfs_clnode.c =================================================================== --- fs/nfsclient/nfs_clnode.c (.../head/sys) (revision 247097) +++ fs/nfsclient/nfs_clnode.c (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -216,10 +216,10 @@ ncl_inactive(struct vop_inactive_args *ap) * stateid is available for the writes. */ if (vp->v_object != NULL) { - VM_OBJECT_LOCK(vp->v_object); + VM_OBJECT_WLOCK(vp->v_object); retv = vm_object_page_clean(vp->v_object, 0, 0, OBJPC_SYNC); - VM_OBJECT_UNLOCK(vp->v_object); + VM_OBJECT_WUNLOCK(vp->v_object); } else retv = TRUE; if (retv == TRUE) { Index: fs/tmpfs/tmpfs_subr.c =================================================================== --- fs/tmpfs/tmpfs_subr.c (.../head/sys) (revision 247097) +++ fs/tmpfs/tmpfs_subr.c (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -38,9 +38,11 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include #include +#include #include #include #include @@ -1270,7 +1272,7 @@ tmpfs_reg_resize(struct vnode *vp, off_t newsize, tmpfs_pages_check_avail(tmp, newpages - oldpages) == 0) return (ENOSPC); - VM_OBJECT_LOCK(uobj); + VM_OBJECT_WLOCK(uobj); if (newsize < oldsize) { /* * Zero the truncated part of the last page. @@ -1290,9 +1292,9 @@ retry: } else if (vm_pager_has_page(uobj, idx, NULL, NULL)) { m = vm_page_alloc(uobj, idx, VM_ALLOC_NORMAL); if (m == NULL) { - VM_OBJECT_UNLOCK(uobj); + VM_OBJECT_WUNLOCK(uobj); VM_WAIT; - VM_OBJECT_LOCK(uobj); + VM_OBJECT_WLOCK(uobj); goto retry; } else if (m->valid != VM_PAGE_BITS_ALL) { ma[0] = m; @@ -1312,7 +1314,7 @@ retry: if (ignerr) m = NULL; else { - VM_OBJECT_UNLOCK(uobj); + VM_OBJECT_WUNLOCK(uobj); return (EIO); } } @@ -1334,7 +1336,7 @@ retry: } } uobj->size = newpages; - VM_OBJECT_UNLOCK(uobj); + VM_OBJECT_WUNLOCK(uobj); TMPFS_LOCK(tmp); tmp->tm_pages_used += (newpages - oldpages); Index: fs/tmpfs/tmpfs_vnops.c =================================================================== --- fs/tmpfs/tmpfs_vnops.c (.../head/sys) (revision 247097) +++ fs/tmpfs/tmpfs_vnops.c (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -39,9 +39,11 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include +#include #include #include #include @@ -445,7 +447,7 @@ tmpfs_nocacheread(vm_object_t tobj, vm_pindex_t id vm_page_t m; int error, rv; - VM_OBJECT_LOCK(tobj); + VM_OBJECT_WLOCK(tobj); m = vm_page_grab(tobj, idx, VM_ALLOC_WIRED | VM_ALLOC_NORMAL | VM_ALLOC_RETRY); if (m->valid != VM_PAGE_BITS_ALL) { @@ -455,20 +457,20 @@ tmpfs_nocacheread(vm_object_t tobj, vm_pindex_t id vm_page_lock(m); vm_page_free(m); vm_page_unlock(m); - VM_OBJECT_UNLOCK(tobj); + VM_OBJECT_WUNLOCK(tobj); return (EIO); } } else vm_page_zero_invalid(m, TRUE); } - VM_OBJECT_UNLOCK(tobj); + VM_OBJECT_WUNLOCK(tobj); error = uiomove_fromphys(&m, offset, tlen, uio); - VM_OBJECT_LOCK(tobj); + VM_OBJECT_WLOCK(tobj); vm_page_lock(m); vm_page_unwire(m, TRUE); vm_page_unlock(m); vm_page_wakeup(m); - VM_OBJECT_UNLOCK(tobj); + VM_OBJECT_WUNLOCK(tobj); return (error); } @@ -511,7 +513,7 @@ tmpfs_mappedread(vm_object_t vobj, vm_object_t tob offset = addr & PAGE_MASK; tlen = MIN(PAGE_SIZE - offset, len); - VM_OBJECT_LOCK(vobj); + VM_OBJECT_WLOCK(vobj); lookupvpg: if (((m = vm_page_lookup(vobj, idx)) != NULL) && vm_page_is_valid(m, offset, tlen)) { @@ -525,11 +527,11 @@ lookupvpg: goto lookupvpg; } vm_page_busy(m); - VM_OBJECT_UNLOCK(vobj); + VM_OBJECT_WUNLOCK(vobj); error = uiomove_fromphys(&m, offset, tlen, uio); - VM_OBJECT_LOCK(vobj); + VM_OBJECT_WLOCK(vobj); vm_page_wakeup(m); - VM_OBJECT_UNLOCK(vobj); + VM_OBJECT_WUNLOCK(vobj); return (error); } else if (m != NULL && uio->uio_segflg == UIO_NOCOPY) { KASSERT(offset == 0, @@ -544,7 +546,7 @@ lookupvpg: goto lookupvpg; } vm_page_busy(m); - VM_OBJECT_UNLOCK(vobj); + VM_OBJECT_WUNLOCK(vobj); sched_pin(); sf = sf_buf_alloc(m, SFB_CPUPRIVATE); ma = (char *)sf_buf_kva(sf); @@ -557,14 +559,14 @@ lookupvpg: } sf_buf_free(sf); sched_unpin(); - VM_OBJECT_LOCK(vobj); + VM_OBJECT_WLOCK(vobj); if (error == 0) m->valid = VM_PAGE_BITS_ALL; vm_page_wakeup(m); - VM_OBJECT_UNLOCK(vobj); + VM_OBJECT_WUNLOCK(vobj); return (error); } - VM_OBJECT_UNLOCK(vobj); + VM_OBJECT_WUNLOCK(vobj); error = tmpfs_nocacheread(tobj, idx, offset, tlen, uio); return (error); @@ -634,7 +636,7 @@ tmpfs_mappedwrite(vm_object_t vobj, vm_object_t to offset = addr & PAGE_MASK; tlen = MIN(PAGE_SIZE - offset, len); - VM_OBJECT_LOCK(vobj); + VM_OBJECT_WLOCK(vobj); lookupvpg: if (((vpg = vm_page_lookup(vobj, idx)) != NULL) && vm_page_is_valid(vpg, offset, tlen)) { @@ -649,15 +651,15 @@ lookupvpg: } vm_page_busy(vpg); vm_page_undirty(vpg); - VM_OBJECT_UNLOCK(vobj); + VM_OBJECT_WUNLOCK(vobj); error = uiomove_fromphys(&vpg, offset, tlen, uio); } else { if (vm_page_is_cached(vobj, idx)) vm_page_cache_free(vobj, idx, idx + 1); - VM_OBJECT_UNLOCK(vobj); + VM_OBJECT_WUNLOCK(vobj); vpg = NULL; } - VM_OBJECT_LOCK(tobj); + VM_OBJECT_WLOCK(tobj); tpg = vm_page_grab(tobj, idx, VM_ALLOC_WIRED | VM_ALLOC_NORMAL | VM_ALLOC_RETRY); if (tpg->valid != VM_PAGE_BITS_ALL) { @@ -673,14 +675,14 @@ lookupvpg: } else vm_page_zero_invalid(tpg, TRUE); } - VM_OBJECT_UNLOCK(tobj); + VM_OBJECT_WUNLOCK(tobj); if (vpg == NULL) error = uiomove_fromphys(&tpg, offset, tlen, uio); else { KASSERT(vpg->valid == VM_PAGE_BITS_ALL, ("parts of vpg invalid")); pmap_copy_page(vpg, tpg); } - VM_OBJECT_LOCK(tobj); + VM_OBJECT_WLOCK(tobj); if (error == 0) { KASSERT(tpg->valid == VM_PAGE_BITS_ALL, ("parts of tpg invalid")); @@ -691,11 +693,11 @@ lookupvpg: vm_page_unlock(tpg); vm_page_wakeup(tpg); out: - VM_OBJECT_UNLOCK(tobj); + VM_OBJECT_WUNLOCK(tobj); if (vpg != NULL) { - VM_OBJECT_LOCK(vobj); + VM_OBJECT_WLOCK(vobj); vm_page_wakeup(vpg); - VM_OBJECT_UNLOCK(vobj); + VM_OBJECT_WUNLOCK(vobj); } return (error); Index: fs/procfs/procfs_map.c =================================================================== --- fs/procfs/procfs_map.c (.../head/sys) (revision 247097) +++ fs/procfs/procfs_map.c (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -43,9 +43,9 @@ #include #include #include -#include #include #include +#include #include #ifdef COMPAT_FREEBSD32 #include @@ -132,7 +132,7 @@ procfs_doprocmap(PFS_FILL_ARGS) privateresident = 0; obj = entry->object.vm_object; if (obj != NULL) { - VM_OBJECT_LOCK(obj); + VM_OBJECT_WLOCK(obj); if (obj->shadow_count == 1) privateresident = obj->resident_page_count; } @@ -148,9 +148,9 @@ procfs_doprocmap(PFS_FILL_ARGS) for (lobj = tobj = obj; tobj; tobj = tobj->backing_object) { if (tobj != obj) - VM_OBJECT_LOCK(tobj); + VM_OBJECT_WLOCK(tobj); if (lobj != obj) - VM_OBJECT_UNLOCK(lobj); + VM_OBJECT_WUNLOCK(lobj); lobj = tobj; } last_timestamp = map->timestamp; @@ -181,12 +181,12 @@ procfs_doprocmap(PFS_FILL_ARGS) break; } if (lobj != obj) - VM_OBJECT_UNLOCK(lobj); + VM_OBJECT_WUNLOCK(lobj); flags = obj->flags; ref_count = obj->ref_count; shadow_count = obj->shadow_count; - VM_OBJECT_UNLOCK(obj); + VM_OBJECT_WUNLOCK(obj); if (vp != NULL) { vn_fullpath(td, vp, &fullpath, &freepath); vrele(vp); Index: fs/fuse/fuse_vnops.c =================================================================== --- fs/fuse/fuse_vnops.c (.../head/sys) (revision 247097) +++ fs/fuse/fuse_vnops.c (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -67,7 +67,7 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include +#include #include #include #include @@ -1758,7 +1758,7 @@ fuse_vnop_getpages(struct vop_getpages_args *ap) * can only occur at the file EOF. */ - VM_OBJECT_LOCK(vp->v_object); + VM_OBJECT_WLOCK(vp->v_object); fuse_vm_page_lock_queues(); if (pages[ap->a_reqpage]->valid != 0) { for (i = 0; i < npages; ++i) { @@ -1769,11 +1769,11 @@ fuse_vnop_getpages(struct vop_getpages_args *ap) } } fuse_vm_page_unlock_queues(); - VM_OBJECT_UNLOCK(vp->v_object); + VM_OBJECT_WUNLOCK(vp->v_object); return 0; } fuse_vm_page_unlock_queues(); - VM_OBJECT_UNLOCK(vp->v_object); + VM_OBJECT_WUNLOCK(vp->v_object); /* * We use only the kva address for the buffer, but this is extremely @@ -1803,7 +1803,7 @@ fuse_vnop_getpages(struct vop_getpages_args *ap) if (error && (uio.uio_resid == count)) { FS_DEBUG("error %d\n", error); - VM_OBJECT_LOCK(vp->v_object); + VM_OBJECT_WLOCK(vp->v_object); fuse_vm_page_lock_queues(); for (i = 0; i < npages; ++i) { if (i != ap->a_reqpage) { @@ -1813,7 +1813,7 @@ fuse_vnop_getpages(struct vop_getpages_args *ap) } } fuse_vm_page_unlock_queues(); - VM_OBJECT_UNLOCK(vp->v_object); + VM_OBJECT_WUNLOCK(vp->v_object); return VM_PAGER_ERROR; } /* @@ -1823,7 +1823,7 @@ fuse_vnop_getpages(struct vop_getpages_args *ap) */ size = count - uio.uio_resid; - VM_OBJECT_LOCK(vp->v_object); + VM_OBJECT_WLOCK(vp->v_object); fuse_vm_page_lock_queues(); for (i = 0, toff = 0; i < npages; i++, toff = nextoff) { vm_page_t m; @@ -1886,7 +1886,7 @@ fuse_vnop_getpages(struct vop_getpages_args *ap) } } fuse_vm_page_unlock_queues(); - VM_OBJECT_UNLOCK(vp->v_object); + VM_OBJECT_WUNLOCK(vp->v_object); return 0; } @@ -1975,9 +1975,9 @@ fuse_vnop_putpages(struct vop_putpages_args *ap) for (i = 0; i < nwritten; i++) { rtvals[i] = VM_PAGER_OK; - VM_OBJECT_LOCK(pages[i]->object); + VM_OBJECT_WLOCK(pages[i]->object); vm_page_undirty(pages[i]); - VM_OBJECT_UNLOCK(pages[i]->object); + VM_OBJECT_WUNLOCK(pages[i]->object); } } return rtvals[0]; Index: fs/fuse/fuse_io.c =================================================================== --- fs/fuse/fuse_io.c (.../head/sys) (revision 247097) +++ fs/fuse/fuse_io.c (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -69,6 +69,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -87,8 +88,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include -#include #include #include "fuse.h" @@ -787,9 +786,9 @@ fuse_io_invalbuf(struct vnode *vp, struct thread * fvdat->flag |= FN_FLUSHINPROG; if (vp->v_bufobj.bo_object != NULL) { - VM_OBJECT_LOCK(vp->v_bufobj.bo_object); + VM_OBJECT_WLOCK(vp->v_bufobj.bo_object); vm_object_page_clean(vp->v_bufobj.bo_object, 0, 0, OBJPC_SYNC); - VM_OBJECT_UNLOCK(vp->v_bufobj.bo_object); + VM_OBJECT_WUNLOCK(vp->v_bufobj.bo_object); } error = vinvalbuf(vp, V_SAVE, PCATCH, 0); while (error) { Index: fs/nfsserver/nfs_nfsdport.c =================================================================== --- fs/nfsserver/nfs_nfsdport.c (.../head/sys) (revision 247097) +++ fs/nfsserver/nfs_nfsdport.c (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -1267,9 +1267,9 @@ nfsvno_fsync(struct vnode *vp, u_int64_t off, int */ if (vp->v_object && (vp->v_object->flags & OBJ_MIGHTBEDIRTY)) { - VM_OBJECT_LOCK(vp->v_object); + VM_OBJECT_WLOCK(vp->v_object); vm_object_page_clean(vp->v_object, 0, 0, OBJPC_SYNC); - VM_OBJECT_UNLOCK(vp->v_object); + VM_OBJECT_WUNLOCK(vp->v_object); } error = VOP_FSYNC(vp, MNT_WAIT, td); } else { @@ -1298,10 +1298,10 @@ nfsvno_fsync(struct vnode *vp, u_int64_t off, int if (vp->v_object && (vp->v_object->flags & OBJ_MIGHTBEDIRTY)) { - VM_OBJECT_LOCK(vp->v_object); + VM_OBJECT_WLOCK(vp->v_object); vm_object_page_clean(vp->v_object, off, off + cnt, OBJPC_SYNC); - VM_OBJECT_UNLOCK(vp->v_object); + VM_OBJECT_WUNLOCK(vp->v_object); } bo = &vp->v_bufobj; Index: mips/gxemul/gxemul_machdep.c =================================================================== --- mips/gxemul/gxemul_machdep.c (.../head/sys) (revision 247097) +++ mips/gxemul/gxemul_machdep.c (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -52,7 +52,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include #include Index: mips/rt305x/rt305x_machdep.c =================================================================== --- mips/rt305x/rt305x_machdep.c (.../head/sys) (revision 247097) +++ mips/rt305x/rt305x_machdep.c (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -54,7 +54,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include #include Index: mips/mips/pmap.c =================================================================== --- mips/mips/pmap.c (.../head/sys) (revision 247097) +++ mips/mips/pmap.c (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -2399,7 +2399,7 @@ pmap_enter_object(pmap_t pmap, vm_offset_t start, vm_page_t m, mpte; vm_pindex_t diff, psize; - VM_OBJECT_LOCK_ASSERT(m_start->object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(m_start->object, RA_WLOCKED); psize = atop(end - start); mpte = NULL; m = m_start; @@ -2423,7 +2423,7 @@ void pmap_object_init_pt(pmap_t pmap, vm_offset_t addr, vm_object_t object, vm_pindex_t pindex, vm_size_t size) { - VM_OBJECT_LOCK_ASSERT(object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(object, RA_WLOCKED); KASSERT(object->type == OBJT_DEVICE || object->type == OBJT_SG, ("pmap_object_init_pt: non-device object")); } @@ -2768,7 +2768,7 @@ pmap_remove_write(vm_page_t m) * another thread while the object is locked. Thus, if PGA_WRITEABLE * is clear, no page table entries need updating. */ - VM_OBJECT_LOCK_ASSERT(m->object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(m->object, RA_WLOCKED); if ((m->oflags & VPO_BUSY) == 0 && (m->aflags & PGA_WRITEABLE) == 0) return; @@ -2834,7 +2834,7 @@ pmap_is_modified(vm_page_t m) * concurrently set while the object is locked. Thus, if PGA_WRITEABLE * is clear, no PTEs can have PTE_D set. */ - VM_OBJECT_LOCK_ASSERT(m->object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(m->object, RA_WLOCKED); if ((m->oflags & VPO_BUSY) == 0 && (m->aflags & PGA_WRITEABLE) == 0) return (FALSE); @@ -2882,7 +2882,7 @@ pmap_clear_modify(vm_page_t m) KASSERT((m->oflags & VPO_UNMANAGED) == 0, ("pmap_clear_modify: page %p is not managed", m)); - VM_OBJECT_LOCK_ASSERT(m->object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(m->object, RA_WLOCKED); KASSERT((m->oflags & VPO_BUSY) == 0, ("pmap_clear_modify: page %p is busy", m)); Index: mips/mips/machdep.c =================================================================== --- mips/mips/machdep.c (.../head/sys) (revision 247097) +++ mips/mips/machdep.c (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -58,6 +58,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include Index: mips/adm5120/adm5120_machdep.c =================================================================== --- mips/adm5120/adm5120_machdep.c (.../head/sys) (revision 247097) +++ mips/adm5120/adm5120_machdep.c (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -53,7 +53,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include #include Index: mips/sentry5/s5_machdep.c =================================================================== --- mips/sentry5/s5_machdep.c (.../head/sys) (revision 247097) +++ mips/sentry5/s5_machdep.c (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -53,7 +53,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include #include Index: mips/idt/idt_machdep.c =================================================================== --- mips/idt/idt_machdep.c (.../head/sys) (revision 247097) +++ mips/idt/idt_machdep.c (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -55,7 +55,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include #include Index: mips/beri/beri_machdep.c =================================================================== --- mips/beri/beri_machdep.c (.../head/sys) (revision 247097) +++ mips/beri/beri_machdep.c (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -64,7 +64,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include #include Index: mips/alchemy/alchemy_machdep.c =================================================================== --- mips/alchemy/alchemy_machdep.c (.../head/sys) (revision 247097) +++ mips/alchemy/alchemy_machdep.c (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -53,7 +53,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include #include Index: mips/cavium/octeon_machdep.c =================================================================== --- mips/cavium/octeon_machdep.c (.../head/sys) (revision 247097) +++ mips/cavium/octeon_machdep.c (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -55,7 +55,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include #include Index: mips/malta/malta_machdep.c =================================================================== --- mips/malta/malta_machdep.c (.../head/sys) (revision 247097) +++ mips/malta/malta_machdep.c (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -54,7 +54,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include #include Index: mips/sibyte/sb_machdep.c =================================================================== --- mips/sibyte/sb_machdep.c (.../head/sys) (revision 247097) +++ mips/sibyte/sb_machdep.c (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -55,7 +55,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include #include Index: amd64/amd64/pmap.c =================================================================== --- amd64/amd64/pmap.c (.../head/sys) (revision 247097) +++ amd64/amd64/pmap.c (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -3492,9 +3492,8 @@ pmap_enter(pmap_t pmap, vm_offset_t va, vm_prot_t KASSERT((m->oflags & VPO_UNMANAGED) != 0 || va < kmi.clean_sva || va >= kmi.clean_eva, ("pmap_enter: managed mapping within the clean submap")); - KASSERT((m->oflags & (VPO_UNMANAGED | VPO_BUSY)) != 0 || - VM_OBJECT_LOCKED(m->object), - ("pmap_enter: page %p is not busy", m)); + if ((m->oflags & (VPO_UNMANAGED | VPO_BUSY)) == 0) + VM_OBJECT_LOCK_ASSERT(m->object, RA_WLOCKED); pa = VM_PAGE_TO_PHYS(m); newpte = (pt_entry_t)(pa | PG_A | PG_V); if ((access & VM_PROT_WRITE) != 0) @@ -3761,7 +3760,7 @@ pmap_enter_object(pmap_t pmap, vm_offset_t start, vm_page_t m, mpte; vm_pindex_t diff, psize; - VM_OBJECT_LOCK_ASSERT(m_start->object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(m_start->object, RA_WLOCKED); psize = atop(end - start); mpte = NULL; m = m_start; @@ -3943,7 +3942,7 @@ pmap_object_init_pt(pmap_t pmap, vm_offset_t addr, vm_page_t p, pdpg; int pat_mode; - VM_OBJECT_LOCK_ASSERT(object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(object, RA_WLOCKED); KASSERT(object->type == OBJT_DEVICE || object->type == OBJT_SG, ("pmap_object_init_pt: non-device object")); if ((addr & (NBPDR - 1)) == 0 && (size & (NBPDR - 1)) == 0) { @@ -4557,7 +4556,7 @@ pmap_is_modified(vm_page_t m) * concurrently set while the object is locked. Thus, if PGA_WRITEABLE * is clear, no PTEs can have PG_M set. */ - VM_OBJECT_LOCK_ASSERT(m->object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(m->object, RA_WLOCKED); if ((m->oflags & VPO_BUSY) == 0 && (m->aflags & PGA_WRITEABLE) == 0) return (FALSE); @@ -4688,7 +4687,7 @@ pmap_remove_write(vm_page_t m) * another thread while the object is locked. Thus, if PGA_WRITEABLE * is clear, no page table entries need updating. */ - VM_OBJECT_LOCK_ASSERT(m->object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(m->object, RA_WLOCKED); if ((m->oflags & VPO_BUSY) == 0 && (m->aflags & PGA_WRITEABLE) == 0) return; @@ -4832,7 +4831,7 @@ pmap_clear_modify(vm_page_t m) KASSERT((m->oflags & VPO_UNMANAGED) == 0, ("pmap_clear_modify: page %p is not managed", m)); - VM_OBJECT_LOCK_ASSERT(m->object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(m->object, RA_WLOCKED); KASSERT((m->oflags & VPO_BUSY) == 0, ("pmap_clear_modify: page %p is busy", m)); Index: amd64/amd64/machdep.c =================================================================== --- amd64/amd64/machdep.c (.../head/sys) (revision 247097) +++ amd64/amd64/machdep.c (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -80,6 +80,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #ifdef SMP Index: ofed/drivers/infiniband/core/umem.c =================================================================== --- ofed/drivers/infiniband/core/umem.c (.../head/sys) (revision 247097) +++ ofed/drivers/infiniband/core/umem.c (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -140,10 +140,10 @@ static void __ib_umem_release(struct ib_device *de struct page *page = sg_page(&chunk->page_list[i]); if (umem->writable && dirty) { if (object && object != page->object) - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); if (object != page->object) { object = page->object; - VM_OBJECT_LOCK(object); + VM_OBJECT_WLOCK(object); } vm_page_dirty(page); } @@ -151,7 +151,7 @@ static void __ib_umem_release(struct ib_device *de kfree(chunk); } if (object) - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); #endif } Index: ofed/include/linux/linux_compat.c =================================================================== --- ofed/include/linux/linux_compat.c (.../head/sys) (revision 247097) +++ ofed/include/linux/linux_compat.c (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -37,6 +37,7 @@ #include #include #include +#include #include #include Index: arm/s3c2xx0/s3c24x0_machdep.c =================================================================== --- arm/s3c2xx0/s3c24x0_machdep.c (.../head/sys) (revision 247097) +++ arm/s3c2xx0/s3c24x0_machdep.c (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -63,6 +63,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include Index: arm/sa11x0/assabet_machdep.c =================================================================== --- arm/sa11x0/assabet_machdep.c (.../head/sys) (revision 247097) +++ arm/sa11x0/assabet_machdep.c (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -66,6 +66,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include Index: arm/at91/at91_machdep.c =================================================================== --- arm/at91/at91_machdep.c (.../head/sys) (revision 247097) +++ arm/at91/at91_machdep.c (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -61,6 +61,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include Index: arm/arm/machdep.c =================================================================== --- arm/arm/machdep.c (.../head/sys) (revision 247097) +++ arm/arm/machdep.c (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -70,6 +70,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include Index: arm/arm/pmap-v6.c =================================================================== --- arm/arm/pmap-v6.c (.../head/sys) (revision 247097) +++ arm/arm/pmap-v6.c (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -2213,7 +2213,7 @@ pmap_object_init_pt(pmap_t pmap, vm_offset_t addr, vm_pindex_t pindex, vm_size_t size) { - VM_OBJECT_LOCK_ASSERT(object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(object, RA_WLOCKED); KASSERT(object->type == OBJT_DEVICE || object->type == OBJT_SG, ("pmap_object_init_pt: non-device object")); } @@ -3429,7 +3429,7 @@ pmap_clear_modify(vm_page_t m) KASSERT((m->oflags & VPO_UNMANAGED) == 0, ("pmap_clear_modify: page %p is not managed", m)); - VM_OBJECT_LOCK_ASSERT(m->object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(m->object, RA_WLOCKED); KASSERT((m->oflags & VPO_BUSY) == 0, ("pmap_clear_modify: page %p is busy", m)); @@ -3476,7 +3476,7 @@ pmap_remove_write(vm_page_t m) * another thread while the object is locked. Thus, if PGA_WRITEABLE * is clear, no page table entries need updating. */ - VM_OBJECT_LOCK_ASSERT(m->object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(m->object, RA_WLOCKED); if ((m->oflags & VPO_BUSY) != 0 || (m->aflags & PGA_WRITEABLE) != 0) pmap_clearbit(m, PVF_WRITE); Index: arm/arm/pmap.c =================================================================== --- arm/arm/pmap.c (.../head/sys) (revision 247097) +++ arm/arm/pmap.c (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -3007,7 +3007,7 @@ pmap_object_init_pt(pmap_t pmap, vm_offset_t addr, vm_pindex_t pindex, vm_size_t size) { - VM_OBJECT_LOCK_ASSERT(object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(object, RA_WLOCKED); KASSERT(object->type == OBJT_DEVICE || object->type == OBJT_SG, ("pmap_object_init_pt: non-device object")); } @@ -4462,7 +4462,7 @@ pmap_clear_modify(vm_page_t m) KASSERT((m->oflags & VPO_UNMANAGED) == 0, ("pmap_clear_modify: page %p is not managed", m)); - VM_OBJECT_LOCK_ASSERT(m->object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(m->object, RA_WLOCKED); KASSERT((m->oflags & VPO_BUSY) == 0, ("pmap_clear_modify: page %p is busy", m)); @@ -4524,7 +4524,7 @@ pmap_remove_write(vm_page_t m) * another thread while the object is locked. Thus, if PGA_WRITEABLE * is clear, no page table entries need updating. */ - VM_OBJECT_LOCK_ASSERT(m->object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(m->object, RA_WLOCKED); if ((m->oflags & VPO_BUSY) != 0 || (m->aflags & PGA_WRITEABLE) != 0) pmap_clearbit(m, PVF_WRITE); Index: arm/xscale/i80321/iq31244_machdep.c =================================================================== --- arm/xscale/i80321/iq31244_machdep.c (.../head/sys) (revision 247097) +++ arm/xscale/i80321/iq31244_machdep.c (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -63,6 +63,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include Index: arm/xscale/i80321/ep80219_machdep.c =================================================================== --- arm/xscale/i80321/ep80219_machdep.c (.../head/sys) (revision 247097) +++ arm/xscale/i80321/ep80219_machdep.c (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -63,6 +63,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include Index: arm/xscale/pxa/pxa_machdep.c =================================================================== --- arm/xscale/pxa/pxa_machdep.c (.../head/sys) (revision 247097) +++ arm/xscale/pxa/pxa_machdep.c (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -65,6 +65,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include Index: arm/xscale/ixp425/avila_machdep.c =================================================================== --- arm/xscale/ixp425/avila_machdep.c (.../head/sys) (revision 247097) +++ arm/xscale/ixp425/avila_machdep.c (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -63,6 +63,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include Index: arm/xscale/i8134x/crb_machdep.c =================================================================== --- arm/xscale/i8134x/crb_machdep.c (.../head/sys) (revision 247097) +++ arm/xscale/i8134x/crb_machdep.c (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -63,6 +63,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include Index: arm/econa/econa_machdep.c =================================================================== --- arm/econa/econa_machdep.c (.../head/sys) (revision 247097) +++ arm/econa/econa_machdep.c (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -53,6 +53,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include Index: powerpc/booke/pmap.c =================================================================== --- powerpc/booke/pmap.c (.../head/sys) (revision 247097) +++ powerpc/booke/pmap.c (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -1561,9 +1561,8 @@ mmu_booke_enter_locked(mmu_t mmu, pmap_t pmap, vm_ KASSERT((va <= VM_MAXUSER_ADDRESS), ("mmu_booke_enter_locked: user pmap, non user va")); } - KASSERT((m->oflags & (VPO_UNMANAGED | VPO_BUSY)) != 0 || - VM_OBJECT_LOCKED(m->object), - ("mmu_booke_enter_locked: page %p is not busy", m)); + if ((m->oflags & (VPO_UNMANAGED | VPO_BUSY)) == 0) + VM_OBJECT_LOCK_ASSERT(m->object, RA_WLOCKED); PMAP_LOCK_ASSERT(pmap, MA_OWNED); @@ -1960,7 +1959,7 @@ mmu_booke_remove_write(mmu_t mmu, vm_page_t m) * another thread while the object is locked. Thus, if PGA_WRITEABLE * is clear, no page table entries need updating. */ - VM_OBJECT_LOCK_ASSERT(m->object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(m->object, RA_WLOCKED); if ((m->oflags & VPO_BUSY) == 0 && (m->aflags & PGA_WRITEABLE) == 0) return; @@ -2175,7 +2174,7 @@ mmu_booke_is_modified(mmu_t mmu, vm_page_t m) * concurrently set while the object is locked. Thus, if PGA_WRITEABLE * is clear, no PTEs can be modified. */ - VM_OBJECT_LOCK_ASSERT(m->object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(m->object, RA_WLOCKED); if ((m->oflags & VPO_BUSY) == 0 && (m->aflags & PGA_WRITEABLE) == 0) return (rv); @@ -2247,7 +2246,7 @@ mmu_booke_clear_modify(mmu_t mmu, vm_page_t m) KASSERT((m->oflags & VPO_UNMANAGED) == 0, ("mmu_booke_clear_modify: page %p is not managed", m)); - VM_OBJECT_LOCK_ASSERT(m->object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(m->object, RA_WLOCKED); KASSERT((m->oflags & VPO_BUSY) == 0, ("mmu_booke_clear_modify: page %p is busy", m)); @@ -2662,7 +2661,7 @@ mmu_booke_object_init_pt(mmu_t mmu, pmap_t pmap, v vm_object_t object, vm_pindex_t pindex, vm_size_t size) { - VM_OBJECT_LOCK_ASSERT(object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(object, RA_WLOCKED); KASSERT(object->type == OBJT_DEVICE || object->type == OBJT_SG, ("mmu_booke_object_init_pt: non-device object")); } Index: powerpc/booke/machdep.c =================================================================== --- powerpc/booke/machdep.c (.../head/sys) (revision 247097) +++ powerpc/booke/machdep.c (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -101,6 +101,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include Index: powerpc/ps3/mmu_ps3.c =================================================================== --- powerpc/ps3/mmu_ps3.c (.../head/sys) (revision 247097) +++ powerpc/ps3/mmu_ps3.c (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -45,7 +45,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include #include Index: powerpc/aim/mmu_oea.c =================================================================== --- powerpc/aim/mmu_oea.c (.../head/sys) (revision 247097) +++ powerpc/aim/mmu_oea.c (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -136,7 +136,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include #include @@ -1122,9 +1121,8 @@ moea_enter_locked(pmap_t pmap, vm_offset_t va, vm_ if (pmap_bootstrapped) rw_assert(&pvh_global_lock, RA_WLOCKED); PMAP_LOCK_ASSERT(pmap, MA_OWNED); - KASSERT((m->oflags & (VPO_UNMANAGED | VPO_BUSY)) != 0 || - VM_OBJECT_LOCKED(m->object), - ("moea_enter_locked: page %p is not busy", m)); + if ((m->oflags & (VPO_UNMANAGED | VPO_BUSY)) == 0) + VM_OBJECT_LOCK_ASSERT(m->object, RA_WLOCKED); /* XXX change the pvo head for fake pages */ if ((m->oflags & VPO_UNMANAGED) != 0) { @@ -1293,7 +1291,7 @@ moea_is_modified(mmu_t mmu, vm_page_t m) * concurrently set while the object is locked. Thus, if PGA_WRITEABLE * is clear, no PTEs can have PTE_CHG set. */ - VM_OBJECT_LOCK_ASSERT(m->object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(m->object, RA_WLOCKED); if ((m->oflags & VPO_BUSY) == 0 && (m->aflags & PGA_WRITEABLE) == 0) return (FALSE); @@ -1333,7 +1331,7 @@ moea_clear_modify(mmu_t mmu, vm_page_t m) KASSERT((m->oflags & VPO_UNMANAGED) == 0, ("moea_clear_modify: page %p is not managed", m)); - VM_OBJECT_LOCK_ASSERT(m->object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(m->object, RA_WLOCKED); KASSERT((m->oflags & VPO_BUSY) == 0, ("moea_clear_modify: page %p is busy", m)); @@ -1368,7 +1366,7 @@ moea_remove_write(mmu_t mmu, vm_page_t m) * another thread while the object is locked. Thus, if PGA_WRITEABLE * is clear, no page table entries need updating. */ - VM_OBJECT_LOCK_ASSERT(m->object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(m->object, RA_WLOCKED); if ((m->oflags & VPO_BUSY) == 0 && (m->aflags & PGA_WRITEABLE) == 0) return; Index: powerpc/aim/mmu_oea64.c =================================================================== --- powerpc/aim/mmu_oea64.c (.../head/sys) (revision 247097) +++ powerpc/aim/mmu_oea64.c (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -140,7 +140,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include #include @@ -1184,9 +1183,8 @@ moea64_enter(mmu_t mmu, pmap_t pmap, vm_offset_t v pvo_flags = PVO_MANAGED; } - KASSERT((m->oflags & (VPO_UNMANAGED | VPO_BUSY)) != 0 || - VM_OBJECT_LOCKED(m->object), - ("moea64_enter: page %p is not busy", m)); + if ((m->oflags & (VPO_UNMANAGED | VPO_BUSY)) == 0) + VM_OBJECT_LOCK_ASSERT(m->object, RA_WLOCKED); /* XXX change the pvo head for fake pages */ if ((m->oflags & VPO_UNMANAGED) != 0) { @@ -1449,7 +1447,7 @@ moea64_is_modified(mmu_t mmu, vm_page_t m) * concurrently set while the object is locked. Thus, if PGA_WRITEABLE * is clear, no PTEs can have LPTE_CHG set. */ - VM_OBJECT_LOCK_ASSERT(m->object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(m->object, RA_WLOCKED); if ((m->oflags & VPO_BUSY) == 0 && (m->aflags & PGA_WRITEABLE) == 0) return (FALSE); @@ -1484,7 +1482,7 @@ moea64_clear_modify(mmu_t mmu, vm_page_t m) KASSERT((m->oflags & VPO_UNMANAGED) == 0, ("moea64_clear_modify: page %p is not managed", m)); - VM_OBJECT_LOCK_ASSERT(m->object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(m->object, RA_WLOCKED); KASSERT((m->oflags & VPO_BUSY) == 0, ("moea64_clear_modify: page %p is busy", m)); @@ -1517,7 +1515,7 @@ moea64_remove_write(mmu_t mmu, vm_page_t m) * another thread while the object is locked. Thus, if PGA_WRITEABLE * is clear, no page table entries need updating. */ - VM_OBJECT_LOCK_ASSERT(m->object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(m->object, RA_WLOCKED); if ((m->oflags & VPO_BUSY) == 0 && (m->aflags & PGA_WRITEABLE) == 0) return; Index: powerpc/aim/machdep.c =================================================================== --- powerpc/aim/machdep.c (.../head/sys) (revision 247097) +++ powerpc/aim/machdep.c (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -84,6 +84,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include Index: powerpc/aim/moea64_native.c =================================================================== --- powerpc/aim/moea64_native.c (.../head/sys) (revision 247097) +++ powerpc/aim/moea64_native.c (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -117,7 +117,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include #include Index: sparc64/sparc64/tsb.c =================================================================== --- sparc64/sparc64/tsb.c (.../head/sys) (revision 247097) +++ sparc64/sparc64/tsb.c (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -53,7 +53,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include #include Index: sparc64/sparc64/pmap.c =================================================================== --- sparc64/sparc64/pmap.c (.../head/sys) (revision 247097) +++ sparc64/sparc64/pmap.c (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -1229,7 +1229,7 @@ pmap_pinit(pmap_t pm) pm->pm_context[i] = -1; CPU_ZERO(&pm->pm_active); - VM_OBJECT_LOCK(pm->pm_tsb_obj); + VM_OBJECT_WLOCK(pm->pm_tsb_obj); for (i = 0; i < TSB_PAGES; i++) { m = vm_page_grab(pm->pm_tsb_obj, i, VM_ALLOC_NOBUSY | VM_ALLOC_RETRY | VM_ALLOC_WIRED | VM_ALLOC_ZERO); @@ -1237,7 +1237,7 @@ pmap_pinit(pmap_t pm) m->md.pmap = pm; ma[i] = m; } - VM_OBJECT_UNLOCK(pm->pm_tsb_obj); + VM_OBJECT_WUNLOCK(pm->pm_tsb_obj); pmap_qenter((vm_offset_t)pm->pm_tsb, ma, TSB_PAGES); bzero(&pm->pm_stats, sizeof(pm->pm_stats)); @@ -1291,7 +1291,7 @@ pmap_release(pmap_t pm) pmap_qremove((vm_offset_t)pm->pm_tsb, TSB_PAGES); obj = pm->pm_tsb_obj; - VM_OBJECT_LOCK(obj); + VM_OBJECT_WLOCK(obj); KASSERT(obj->ref_count == 1, ("pmap_release: tsbobj ref count != 1")); while (!TAILQ_EMPTY(&obj->memq)) { m = TAILQ_FIRST(&obj->memq); @@ -1300,7 +1300,7 @@ pmap_release(pmap_t pm) atomic_subtract_int(&cnt.v_wire_count, 1); vm_page_free_zero(m); } - VM_OBJECT_UNLOCK(obj); + VM_OBJECT_WUNLOCK(obj); PMAP_LOCK_DESTROY(pm); } @@ -1494,9 +1494,8 @@ pmap_enter_locked(pmap_t pm, vm_offset_t va, vm_pa rw_assert(&tte_list_global_lock, RA_WLOCKED); PMAP_LOCK_ASSERT(pm, MA_OWNED); - KASSERT((m->oflags & (VPO_UNMANAGED | VPO_BUSY)) != 0 || - VM_OBJECT_LOCKED(m->object), - ("pmap_enter_locked: page %p is not busy", m)); + if ((m->oflags & (VPO_UNMANAGED | VPO_BUSY)) == 0) + VM_OBJECT_LOCK_ASSERT(m->object, RA_WLOCKED); PMAP_STATS_INC(pmap_nenter); pa = VM_PAGE_TO_PHYS(m); @@ -1663,7 +1662,7 @@ pmap_object_init_pt(pmap_t pm, vm_offset_t addr, v vm_pindex_t pindex, vm_size_t size) { - VM_OBJECT_LOCK_ASSERT(object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(object, RA_WLOCKED); KASSERT(object->type == OBJT_DEVICE || object->type == OBJT_SG, ("pmap_object_init_pt: non-device object")); } @@ -2061,7 +2060,7 @@ pmap_is_modified(vm_page_t m) * concurrently set while the object is locked. Thus, if PGA_WRITEABLE * is clear, no TTEs can have TD_W set. */ - VM_OBJECT_LOCK_ASSERT(m->object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(m->object, RA_WLOCKED); if ((m->oflags & VPO_BUSY) == 0 && (m->aflags & PGA_WRITEABLE) == 0) return (rv); @@ -2129,7 +2128,7 @@ pmap_clear_modify(vm_page_t m) KASSERT((m->oflags & VPO_UNMANAGED) == 0, ("pmap_clear_modify: page %p is not managed", m)); - VM_OBJECT_LOCK_ASSERT(m->object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(m->object, RA_WLOCKED); KASSERT((m->oflags & VPO_BUSY) == 0, ("pmap_clear_modify: page %p is busy", m)); @@ -2184,7 +2183,7 @@ pmap_remove_write(vm_page_t m) * another thread while the object is locked. Thus, if PGA_WRITEABLE * is clear, no page table entries need updating. */ - VM_OBJECT_LOCK_ASSERT(m->object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(m->object, RA_WLOCKED); if ((m->oflags & VPO_BUSY) == 0 && (m->aflags & PGA_WRITEABLE) == 0) return; Index: sparc64/sparc64/machdep.c =================================================================== --- sparc64/sparc64/machdep.c (.../head/sys) (revision 247097) +++ sparc64/sparc64/machdep.c (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -65,6 +65,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include Index: vm/vm_object.h =================================================================== --- vm/vm_object.h (.../head/sys) (revision 247097) +++ vm/vm_object.h (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -70,15 +70,16 @@ #include #include #include +#include /* * Types defined: * * vm_object_t Virtual memory object. * - * The root of cached pages pool is protected by both the per-object mutex + * The root of cached pages pool is protected by both the per-object lock * and the free pages queue mutex. - * On insert in the cache splay tree, the per-object mutex is expected + * On insert in the cache splay tree, the per-object lock is expected * to be already held and the free pages queue mutex will be * acquired during the operation too. * On remove and lookup from the cache splay tree, only the free @@ -89,13 +90,13 @@ * * List of locks * (c) const until freed - * (o) per-object mutex + * (o) per-object lock * (f) free pages queue mutex * */ struct vm_object { - struct mtx mtx; + struct rwlock lock; TAILQ_ENTRY(vm_object) object_list; /* list of all objects */ LIST_HEAD(, vm_object) shadow_head; /* objects that this is a shadow for */ LIST_ENTRY(vm_object) shadow_list; /* chain of shadow objects */ @@ -203,16 +204,24 @@ extern struct vm_object kmem_object_store; #define kernel_object (&kernel_object_store) #define kmem_object (&kmem_object_store) -#define VM_OBJECT_LOCK(object) mtx_lock(&(object)->mtx) -#define VM_OBJECT_LOCK_ASSERT(object, type) \ - mtx_assert(&(object)->mtx, (type)) -#define VM_OBJECT_LOCK_INIT(object, type) \ - mtx_init(&(object)->mtx, "vm object", \ - (type), MTX_DEF | MTX_DUPOK) -#define VM_OBJECT_LOCKED(object) mtx_owned(&(object)->mtx) -#define VM_OBJECT_MTX(object) (&(object)->mtx) -#define VM_OBJECT_TRYLOCK(object) mtx_trylock(&(object)->mtx) -#define VM_OBJECT_UNLOCK(object) mtx_unlock(&(object)->mtx) +#define VM_OBJECT_LOCK_ASSERT(object, type) \ + rw_assert(&(object)->lock, (type)) +#define VM_OBJECT_LOCK_INIT(object, name) \ + rw_init_flags(&(object)->lock, (name), RW_DUPOK) +#define VM_OBJECT_RLOCK(object) \ + rw_rlock(&(object)->lock) +#define VM_OBJECT_RUNLOCK(object) \ + rw_runlock(&(object)->lock) +#define VM_OBJECT_SLEEP(wchan, object, pri, wmesg, timo) \ + rw_sleep((wchan), &(object)->lock, (pri), (wmesg), (timo)) +#define VM_OBJECT_TRYRLOCK(object) \ + rw_try_rlock(&(object)->lock) +#define VM_OBJECT_TRYWLOCK(object) \ + rw_try_wlock(&(object)->lock) +#define VM_OBJECT_WLOCK(object) \ + rw_wlock(&(object)->lock) +#define VM_OBJECT_WUNLOCK(object) \ + rw_wunlock(&(object)->lock) /* * The object must be locked or thread private. Index: vm/vm_meter.c =================================================================== --- vm/vm_meter.c (.../head/sys) (revision 247097) +++ vm/vm_meter.c (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -39,6 +39,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -110,7 +111,7 @@ vmtotal(SYSCTL_HANDLER_ARGS) */ mtx_lock(&vm_object_list_mtx); TAILQ_FOREACH(object, &vm_object_list, object_list) { - if (!VM_OBJECT_TRYLOCK(object)) { + if (!VM_OBJECT_TRYWLOCK(object)) { /* * Avoid a lock-order reversal. Consequently, * the reported number of active pages may be @@ -119,7 +120,7 @@ vmtotal(SYSCTL_HANDLER_ARGS) continue; } vm_object_clear_flag(object, OBJ_ACTIVE); - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); } mtx_unlock(&vm_object_list_mtx); /* @@ -178,10 +179,10 @@ vmtotal(SYSCTL_HANDLER_ARGS) if ((entry->eflags & MAP_ENTRY_IS_SUB_MAP) || (object = entry->object.vm_object) == NULL) continue; - VM_OBJECT_LOCK(object); + VM_OBJECT_WLOCK(object); vm_object_set_flag(object, OBJ_ACTIVE); paging |= object->paging_in_progress; - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); } vm_map_unlock_read(map); vmspace_free(vm); Index: vm/vm_page.c =================================================================== --- vm/vm_page.c (.../head/sys) (revision 247097) +++ vm/vm_page.c (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -96,6 +96,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -468,7 +469,7 @@ void vm_page_busy(vm_page_t m) { - VM_OBJECT_LOCK_ASSERT(m->object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(m->object, RA_WLOCKED); KASSERT((m->oflags & VPO_BUSY) == 0, ("vm_page_busy: page already busy!!!")); m->oflags |= VPO_BUSY; @@ -483,7 +484,7 @@ void vm_page_flash(vm_page_t m) { - VM_OBJECT_LOCK_ASSERT(m->object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(m->object, RA_WLOCKED); if (m->oflags & VPO_WANTED) { m->oflags &= ~VPO_WANTED; wakeup(m); @@ -501,7 +502,7 @@ void vm_page_wakeup(vm_page_t m) { - VM_OBJECT_LOCK_ASSERT(m->object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(m->object, RA_WLOCKED); KASSERT(m->oflags & VPO_BUSY, ("vm_page_wakeup: page not busy!!!")); m->oflags &= ~VPO_BUSY; vm_page_flash(m); @@ -511,7 +512,7 @@ void vm_page_io_start(vm_page_t m) { - VM_OBJECT_LOCK_ASSERT(m->object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(m->object, RA_WLOCKED); m->busy++; } @@ -519,7 +520,7 @@ void vm_page_io_finish(vm_page_t m) { - VM_OBJECT_LOCK_ASSERT(m->object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(m->object, RA_WLOCKED); KASSERT(m->busy > 0, ("vm_page_io_finish: page %p is not busy", m)); m->busy--; if (m->busy == 0) @@ -751,7 +752,7 @@ void vm_page_sleep(vm_page_t m, const char *msg) { - VM_OBJECT_LOCK_ASSERT(m->object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(m->object, RA_WLOCKED); if (mtx_owned(vm_page_lockptr(m))) vm_page_unlock(m); @@ -763,7 +764,7 @@ vm_page_sleep(vm_page_t m, const char *msg) * it. */ m->oflags |= VPO_WANTED; - msleep(m, VM_OBJECT_MTX(m->object), PVM, msg, 0); + VM_OBJECT_SLEEP(m, m->object, PVM, msg, 0); } /* @@ -866,7 +867,7 @@ vm_page_insert(vm_page_t m, vm_object_t object, vm { vm_page_t root; - VM_OBJECT_LOCK_ASSERT(object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(object, RA_WLOCKED); if (m->object != NULL) panic("vm_page_insert: page already inserted"); @@ -942,7 +943,7 @@ vm_page_remove(vm_page_t m) vm_page_lock_assert(m, MA_OWNED); if ((object = m->object) == NULL) return; - VM_OBJECT_LOCK_ASSERT(object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(object, RA_WLOCKED); if (m->oflags & VPO_BUSY) { m->oflags &= ~VPO_BUSY; vm_page_flash(m); @@ -1016,7 +1017,7 @@ vm_page_lookup(vm_object_t object, vm_pindex_t pin { vm_page_t m; - VM_OBJECT_LOCK_ASSERT(object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(object, RA_WLOCKED); if ((m = object->root) != NULL && m->pindex != pindex) { m = vm_page_splay(pindex, m); if ((object->root = m)->pindex != pindex) @@ -1038,7 +1039,7 @@ vm_page_find_least(vm_object_t object, vm_pindex_t { vm_page_t m; - VM_OBJECT_LOCK_ASSERT(object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(object, RA_WLOCKED); if ((m = TAILQ_FIRST(&object->memq)) != NULL) { if (m->pindex < pindex) { m = vm_page_splay(pindex, object->root); @@ -1060,7 +1061,7 @@ vm_page_next(vm_page_t m) { vm_page_t next; - VM_OBJECT_LOCK_ASSERT(m->object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(m->object, RA_WLOCKED); if ((next = TAILQ_NEXT(m, listq)) != NULL && next->pindex != m->pindex + 1) next = NULL; @@ -1078,7 +1079,7 @@ vm_page_prev(vm_page_t m) { vm_page_t prev; - VM_OBJECT_LOCK_ASSERT(m->object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(m->object, RA_WLOCKED); if ((prev = TAILQ_PREV(m, pglist, listq)) != NULL && prev->pindex != m->pindex - 1) prev = NULL; @@ -1256,7 +1257,7 @@ vm_page_cache_transfer(vm_object_t orig_object, vm * requires the object to be locked. In contrast, removal does * not. */ - VM_OBJECT_LOCK_ASSERT(new_object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(new_object, RA_WLOCKED); KASSERT(new_object->cache == NULL, ("vm_page_cache_transfer: object %p has cached pages", new_object)); @@ -1326,7 +1327,7 @@ vm_page_is_cached(vm_object_t object, vm_pindex_t * page queues lock in order to prove that the specified page doesn't * exist. */ - VM_OBJECT_LOCK_ASSERT(object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(object, RA_WLOCKED); if (__predict_true(object->cache == NULL)) return (FALSE); mtx_lock(&vm_page_queue_free_mtx); @@ -1375,7 +1376,7 @@ vm_page_alloc(vm_object_t object, vm_pindex_t pind KASSERT((object != NULL) == ((req & VM_ALLOC_NOOBJ) == 0), ("vm_page_alloc: inconsistent object/req")); if (object != NULL) - VM_OBJECT_LOCK_ASSERT(object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(object, RA_WLOCKED); req_class = req & VM_ALLOC_CLASS_MASK; @@ -1582,7 +1583,7 @@ vm_page_alloc_contig(vm_object_t object, vm_pindex KASSERT((object != NULL) == ((req & VM_ALLOC_NOOBJ) == 0), ("vm_page_alloc_contig: inconsistent object/req")); if (object != NULL) { - VM_OBJECT_LOCK_ASSERT(object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(object, RA_WLOCKED); KASSERT(object->type == OBJT_PHYS, ("vm_page_alloc_contig: object %p isn't OBJT_PHYS", object)); @@ -1992,7 +1993,7 @@ vm_page_activate(vm_page_t m) int queue; vm_page_lock_assert(m, MA_OWNED); - VM_OBJECT_LOCK_ASSERT(m->object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(m->object, RA_WLOCKED); if ((queue = m->queue) != PQ_ACTIVE) { if (m->wire_count == 0 && (m->oflags & VPO_UNMANAGED) == 0) { if (m->act_count < ACT_INIT) @@ -2276,7 +2277,7 @@ vm_page_try_to_cache(vm_page_t m) { vm_page_lock_assert(m, MA_OWNED); - VM_OBJECT_LOCK_ASSERT(m->object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(m->object, RA_WLOCKED); if (m->dirty || m->hold_count || m->busy || m->wire_count || (m->oflags & (VPO_BUSY | VPO_UNMANAGED)) != 0) return (0); @@ -2299,7 +2300,7 @@ vm_page_try_to_free(vm_page_t m) vm_page_lock_assert(m, MA_OWNED); if (m->object != NULL) - VM_OBJECT_LOCK_ASSERT(m->object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(m->object, RA_WLOCKED); if (m->dirty || m->hold_count || m->busy || m->wire_count || (m->oflags & (VPO_BUSY | VPO_UNMANAGED)) != 0) return (0); @@ -2325,7 +2326,7 @@ vm_page_cache(vm_page_t m) vm_page_lock_assert(m, MA_OWNED); object = m->object; - VM_OBJECT_LOCK_ASSERT(object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(object, RA_WLOCKED); if ((m->oflags & (VPO_UNMANAGED | VPO_BUSY)) || m->busy || m->hold_count || m->wire_count) panic("vm_page_cache: attempting to cache busy page"); @@ -2482,7 +2483,7 @@ vm_page_dontneed(vm_page_t m) int head; vm_page_lock_assert(m, MA_OWNED); - VM_OBJECT_LOCK_ASSERT(m->object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(m->object, RA_WLOCKED); dnw = PCPU_GET(dnweight); PCPU_INC(dnweight); @@ -2547,7 +2548,7 @@ vm_page_grab(vm_object_t object, vm_pindex_t pinde { vm_page_t m; - VM_OBJECT_LOCK_ASSERT(object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(object, RA_WLOCKED); KASSERT((allocflags & VM_ALLOC_RETRY) != 0, ("vm_page_grab: VM_ALLOC_RETRY is required")); retrylookup: @@ -2576,9 +2577,9 @@ retrylookup: m = vm_page_alloc(object, pindex, allocflags & ~(VM_ALLOC_RETRY | VM_ALLOC_IGN_SBUSY)); if (m == NULL) { - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); VM_WAIT; - VM_OBJECT_LOCK(object); + VM_OBJECT_WLOCK(object); goto retrylookup; } else if (m->valid != 0) return (m); @@ -2628,7 +2629,7 @@ vm_page_set_valid_range(vm_page_t m, int base, int { int endoff, frag; - VM_OBJECT_LOCK_ASSERT(m->object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(m->object, RA_WLOCKED); if (size == 0) /* handle degenerate case */ return; @@ -2681,7 +2682,7 @@ vm_page_clear_dirty_mask(vm_page_t m, vm_page_bits * write mapped, then the page's dirty field cannot possibly be * set by a concurrent pmap operation. */ - VM_OBJECT_LOCK_ASSERT(m->object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(m->object, RA_WLOCKED); if ((m->oflags & VPO_BUSY) == 0 && !pmap_page_is_write_mapped(m)) m->dirty &= ~pagebits; else { @@ -2735,7 +2736,7 @@ vm_page_set_validclean(vm_page_t m, int base, int vm_page_bits_t oldvalid, pagebits; int endoff, frag; - VM_OBJECT_LOCK_ASSERT(m->object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(m->object, RA_WLOCKED); if (size == 0) /* handle degenerate case */ return; @@ -2825,7 +2826,7 @@ vm_page_set_invalid(vm_page_t m, int base, int siz { vm_page_bits_t bits; - VM_OBJECT_LOCK_ASSERT(m->object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(m->object, RA_WLOCKED); KASSERT((m->oflags & VPO_BUSY) == 0, ("vm_page_set_invalid: page %p is busy", m)); bits = vm_page_bits(base, size); @@ -2854,7 +2855,7 @@ vm_page_zero_invalid(vm_page_t m, boolean_t setval int b; int i; - VM_OBJECT_LOCK_ASSERT(m->object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(m->object, RA_WLOCKED); /* * Scan the valid bits looking for invalid sections that * must be zerod. Invalid sub-DEV_BSIZE'd areas ( where the @@ -2893,7 +2894,7 @@ vm_page_is_valid(vm_page_t m, int base, int size) { vm_page_bits_t bits; - VM_OBJECT_LOCK_ASSERT(m->object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(m->object, RA_WLOCKED); bits = vm_page_bits(base, size); if (m->valid && ((m->valid & bits) == bits)) return 1; @@ -2908,7 +2909,7 @@ void vm_page_test_dirty(vm_page_t m) { - VM_OBJECT_LOCK_ASSERT(m->object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(m->object, RA_WLOCKED); if (m->dirty != VM_PAGE_BITS_ALL && pmap_is_modified(m)) vm_page_dirty(m); } @@ -2962,7 +2963,7 @@ vm_page_cowfault(vm_page_t m) vm_page_lock_assert(m, MA_OWNED); object = m->object; - VM_OBJECT_LOCK_ASSERT(object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(object, RA_WLOCKED); KASSERT(object->paging_in_progress != 0, ("vm_page_cowfault: object %p's paging-in-progress count is zero.", object)); @@ -2975,9 +2976,9 @@ vm_page_cowfault(vm_page_t m) if (mnew == NULL) { vm_page_insert(m, object, pindex); vm_page_unlock(m); - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); VM_WAIT; - VM_OBJECT_LOCK(object); + VM_OBJECT_WLOCK(object); if (m == vm_page_lookup(object, pindex)) { vm_page_lock(m); goto retry_alloc; @@ -3034,11 +3035,11 @@ vm_page_cowsetup(vm_page_t m) vm_page_lock_assert(m, MA_OWNED); if ((m->flags & PG_FICTITIOUS) != 0 || (m->oflags & VPO_UNMANAGED) != 0 || - m->cow == USHRT_MAX - 1 || !VM_OBJECT_TRYLOCK(m->object)) + m->cow == USHRT_MAX - 1 || !VM_OBJECT_TRYWLOCK(m->object)) return (EBUSY); m->cow++; pmap_remove_write(m); - VM_OBJECT_UNLOCK(m->object); + VM_OBJECT_WUNLOCK(m->object); return (0); } @@ -3055,7 +3056,7 @@ vm_page_object_lock_assert(vm_page_t m) * here. */ if (m->object != NULL && (m->oflags & VPO_BUSY) == 0) - VM_OBJECT_LOCK_ASSERT(m->object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(m->object, RA_WLOCKED); } #endif Index: vm/vm_map.c =================================================================== --- vm/vm_map.c (.../head/sys) (revision 247097) +++ vm/vm_map.c (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -77,6 +77,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -1223,10 +1224,10 @@ charged: * reference counting is insufficient to recognize * aliases with precision.) */ - VM_OBJECT_LOCK(object); + VM_OBJECT_WLOCK(object); if (object->ref_count > 1 || object->shadow_count != 0) vm_object_clear_flag(object, OBJ_ONEMAPPING); - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); } else if ((prev_entry != &map->header) && (prev_entry->eflags == protoeflags) && @@ -1624,12 +1625,12 @@ _vm_map_clip_start(vm_map_t map, vm_map_entry_t en } else if (entry->object.vm_object != NULL && ((entry->eflags & MAP_ENTRY_NEEDS_COPY) == 0) && entry->cred != NULL) { - VM_OBJECT_LOCK(entry->object.vm_object); + VM_OBJECT_WLOCK(entry->object.vm_object); KASSERT(entry->object.vm_object->cred == NULL, ("OVERCOMMIT: vm_entry_clip_start: both cred e %p", entry)); entry->object.vm_object->cred = entry->cred; entry->object.vm_object->charge = entry->end - entry->start; - VM_OBJECT_UNLOCK(entry->object.vm_object); + VM_OBJECT_WUNLOCK(entry->object.vm_object); entry->cred = NULL; } @@ -1701,12 +1702,12 @@ _vm_map_clip_end(vm_map_t map, vm_map_entry_t entr } else if (entry->object.vm_object != NULL && ((entry->eflags & MAP_ENTRY_NEEDS_COPY) == 0) && entry->cred != NULL) { - VM_OBJECT_LOCK(entry->object.vm_object); + VM_OBJECT_WLOCK(entry->object.vm_object); KASSERT(entry->object.vm_object->cred == NULL, ("OVERCOMMIT: vm_entry_clip_end: both cred e %p", entry)); entry->object.vm_object->cred = entry->cred; entry->object.vm_object->charge = entry->end - entry->start; - VM_OBJECT_UNLOCK(entry->object.vm_object); + VM_OBJECT_WUNLOCK(entry->object.vm_object); entry->cred = NULL; } @@ -1806,7 +1807,7 @@ vm_map_pmap_enter(vm_map_t map, vm_offset_t addr, if ((prot & (VM_PROT_READ | VM_PROT_EXECUTE)) == 0 || object == NULL) return; - VM_OBJECT_LOCK(object); + VM_OBJECT_WLOCK(object); if (object->type == OBJT_DEVICE || object->type == OBJT_SG) { pmap_object_init_pt(map->pmap, addr, object, pindex, size); goto unlock_return; @@ -1857,7 +1858,7 @@ vm_map_pmap_enter(vm_map_t map, vm_offset_t addr, pmap_enter_object(map->pmap, start, addr + ptoa(psize), p_start, prot); unlock_return: - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); } /* @@ -1933,9 +1934,9 @@ vm_map_protect(vm_map_t map, vm_offset_t start, vm continue; } - VM_OBJECT_LOCK(obj); + VM_OBJECT_WLOCK(obj); if (obj->type != OBJT_DEFAULT && obj->type != OBJT_SWAP) { - VM_OBJECT_UNLOCK(obj); + VM_OBJECT_WUNLOCK(obj); continue; } @@ -1947,7 +1948,7 @@ vm_map_protect(vm_map_t map, vm_offset_t start, vm KASSERT(obj->charge == 0, ("vm_map_protect: object %p overcharged\n", obj)); if (!swap_reserve(ptoa(obj->size))) { - VM_OBJECT_UNLOCK(obj); + VM_OBJECT_WUNLOCK(obj); vm_map_unlock(map); return (KERN_RESOURCE_SHORTAGE); } @@ -1955,7 +1956,7 @@ vm_map_protect(vm_map_t map, vm_offset_t start, vm crhold(cred); obj->cred = cred; obj->charge = ptoa(obj->size); - VM_OBJECT_UNLOCK(obj); + VM_OBJECT_WUNLOCK(obj); } /* @@ -2718,7 +2719,7 @@ vm_map_entry_delete(vm_map_t map, vm_map_entry_t e count = OFF_TO_IDX(size); offidxstart = OFF_TO_IDX(entry->offset); offidxend = offidxstart + count; - VM_OBJECT_LOCK(object); + VM_OBJECT_WLOCK(object); if (object->ref_count != 1 && ((object->flags & (OBJ_NOSPLIT|OBJ_ONEMAPPING)) == OBJ_ONEMAPPING || object == kernel_object || object == kmem_object)) { @@ -2747,7 +2748,7 @@ vm_map_entry_delete(vm_map_t map, vm_map_entry_t e } } } - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); } else entry->object.vm_object = NULL; if (map->system_map) @@ -2955,7 +2956,7 @@ vm_map_copy_entry( */ size = src_entry->end - src_entry->start; if ((src_object = src_entry->object.vm_object) != NULL) { - VM_OBJECT_LOCK(src_object); + VM_OBJECT_WLOCK(src_object); charged = ENTRY_CHARGED(src_entry); if ((src_object->handle == NULL) && (src_object->type == OBJT_DEFAULT || @@ -2976,7 +2977,7 @@ vm_map_copy_entry( src_object->cred = src_entry->cred; src_object->charge = size; } - VM_OBJECT_UNLOCK(src_object); + VM_OBJECT_WUNLOCK(src_object); dst_entry->object.vm_object = src_object; if (charged) { cred = curthread->td_ucred; @@ -3152,7 +3153,7 @@ vmspace_fork(struct vmspace *vm1, vm_ooffset_t *fo vm_object_deallocate(object); object = old_entry->object.vm_object; } - VM_OBJECT_LOCK(object); + VM_OBJECT_WLOCK(object); vm_object_clear_flag(object, OBJ_ONEMAPPING); if (old_entry->cred != NULL) { KASSERT(object->cred == NULL, ("vmspace_fork both cred")); @@ -3160,7 +3161,7 @@ vmspace_fork(struct vmspace *vm1, vm_ooffset_t *fo object->charge = old_entry->end - old_entry->start; old_entry->cred = NULL; } - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); /* * Clone the entry, referencing the shared object. @@ -3846,10 +3847,10 @@ RetryLookup:; crfree(entry->cred); entry->cred = NULL; } else if (entry->cred != NULL) { - VM_OBJECT_LOCK(eobject); + VM_OBJECT_WLOCK(eobject); eobject->cred = entry->cred; eobject->charge = size; - VM_OBJECT_UNLOCK(eobject); + VM_OBJECT_WUNLOCK(eobject); entry->cred = NULL; } @@ -3874,10 +3875,10 @@ RetryLookup:; atop(size)); entry->offset = 0; if (entry->cred != NULL) { - VM_OBJECT_LOCK(entry->object.vm_object); + VM_OBJECT_WLOCK(entry->object.vm_object); entry->object.vm_object->cred = entry->cred; entry->object.vm_object->charge = size; - VM_OBJECT_UNLOCK(entry->object.vm_object); + VM_OBJECT_WUNLOCK(entry->object.vm_object); entry->cred = NULL; } vm_map_lock_downgrade(map); Index: vm/sg_pager.c =================================================================== --- vm/sg_pager.c (.../head/sys) (revision 247097) +++ vm/sg_pager.c (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -36,6 +36,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -142,10 +143,10 @@ sg_pager_getpages(vm_object_t object, vm_page_t *m size_t space; int i; - VM_OBJECT_LOCK_ASSERT(object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(object, RA_WLOCKED); sg = object->handle; memattr = object->memattr; - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); offset = m[reqpage]->pindex; /* @@ -180,7 +181,7 @@ sg_pager_getpages(vm_object_t object, vm_page_t *m /* Construct a new fake page. */ page = vm_page_getfake(paddr, memattr); - VM_OBJECT_LOCK(object); + VM_OBJECT_WLOCK(object); TAILQ_INSERT_TAIL(&object->un_pager.sgp.sgp_pglist, page, pageq); /* Free the original pages and insert this fake page into the object. */ Index: vm/swap_pager.c =================================================================== --- vm/swap_pager.c (.../head/sys) (revision 247097) +++ vm/swap_pager.c (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -89,6 +89,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -622,14 +623,14 @@ swap_pager_alloc(void *handle, vm_ooffset_t size, crhold(cred); } object = vm_object_allocate(OBJT_DEFAULT, pindex); - VM_OBJECT_LOCK(object); + VM_OBJECT_WLOCK(object); object->handle = handle; if (cred != NULL) { object->cred = cred; object->charge = size; } swp_pager_meta_build(object, 0, SWAPBLK_NONE); - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); } sx_xunlock(&sw_alloc_sx); mtx_unlock(&Giant); @@ -640,13 +641,13 @@ swap_pager_alloc(void *handle, vm_ooffset_t size, crhold(cred); } object = vm_object_allocate(OBJT_DEFAULT, pindex); - VM_OBJECT_LOCK(object); + VM_OBJECT_WLOCK(object); if (cred != NULL) { object->cred = cred; object->charge = size; } swp_pager_meta_build(object, 0, SWAPBLK_NONE); - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); } return (object); } @@ -675,7 +676,7 @@ swap_pager_dealloc(vm_object_t object) mtx_unlock(&sw_alloc_mtx); } - VM_OBJECT_LOCK_ASSERT(object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(object, RA_WLOCKED); vm_object_pip_wait(object, "swpdea"); /* @@ -816,7 +817,7 @@ void swap_pager_freespace(vm_object_t object, vm_pindex_t start, vm_size_t size) { - VM_OBJECT_LOCK_ASSERT(object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(object, RA_WLOCKED); swp_pager_meta_free(object, start, size); } @@ -835,7 +836,7 @@ swap_pager_reserve(vm_object_t object, vm_pindex_t daddr_t blk = SWAPBLK_NONE; vm_pindex_t beg = start; /* save start index */ - VM_OBJECT_LOCK(object); + VM_OBJECT_WLOCK(object); while (size) { if (n == 0) { n = BLIST_MAX_ALLOC; @@ -843,7 +844,7 @@ swap_pager_reserve(vm_object_t object, vm_pindex_t n >>= 1; if (n == 0) { swp_pager_meta_free(object, beg, start - beg); - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); return (-1); } } @@ -855,7 +856,7 @@ swap_pager_reserve(vm_object_t object, vm_pindex_t --n; } swp_pager_meta_free(object, start, n); - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); return (0); } @@ -884,8 +885,8 @@ swap_pager_copy(vm_object_t srcobject, vm_object_t { vm_pindex_t i; - VM_OBJECT_LOCK_ASSERT(srcobject, MA_OWNED); - VM_OBJECT_LOCK_ASSERT(dstobject, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(srcobject, RA_WLOCKED); + VM_OBJECT_LOCK_ASSERT(dstobject, RA_WLOCKED); /* * If destroysource is set, we remove the source object from the @@ -935,11 +936,11 @@ swap_pager_copy(vm_object_t srcobject, vm_object_t * swp_pager_meta_build() can sleep. */ vm_object_pip_add(srcobject, 1); - VM_OBJECT_UNLOCK(srcobject); + VM_OBJECT_WUNLOCK(srcobject); vm_object_pip_add(dstobject, 1); swp_pager_meta_build(dstobject, i, srcaddr); vm_object_pip_wakeup(dstobject); - VM_OBJECT_LOCK(srcobject); + VM_OBJECT_WLOCK(srcobject); vm_object_pip_wakeup(srcobject); } } else { @@ -988,7 +989,7 @@ swap_pager_haspage(vm_object_t object, vm_pindex_t { daddr_t blk0; - VM_OBJECT_LOCK_ASSERT(object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(object, RA_WLOCKED); /* * do we have good backing store at the requested index ? */ @@ -1059,7 +1060,7 @@ static void swap_pager_unswapped(vm_page_t m) { - VM_OBJECT_LOCK_ASSERT(m->object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(m->object, RA_WLOCKED); swp_pager_meta_ctl(m->object, m->pindex, SWM_FREE); } @@ -1148,7 +1149,7 @@ swap_pager_getpages(vm_object_t object, vm_page_t /* * Getpbuf() can sleep. */ - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); /* * Get a swap buffer header to perform the IO */ @@ -1169,7 +1170,7 @@ swap_pager_getpages(vm_object_t object, vm_page_t bp->b_bufsize = PAGE_SIZE * (j - i); bp->b_pager.pg_reqpage = reqpage - i; - VM_OBJECT_LOCK(object); + VM_OBJECT_WLOCK(object); { int k; @@ -1188,7 +1189,7 @@ swap_pager_getpages(vm_object_t object, vm_page_t * does not remove it. */ vm_object_pip_add(object, bp->b_npages); - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); /* * perform the I/O. NOTE!!! bp cannot be considered valid after @@ -1209,11 +1210,11 @@ swap_pager_getpages(vm_object_t object, vm_page_t * cleared on completion. If an I/O error occurs, SWAPBLK_NONE * is set in the meta-data. */ - VM_OBJECT_LOCK(object); + VM_OBJECT_WLOCK(object); while ((mreq->oflags & VPO_SWAPINPROG) != 0) { mreq->oflags |= VPO_WANTED; PCPU_INC(cnt.v_intrans); - if (msleep(mreq, VM_OBJECT_MTX(object), PSWP, "swread", hz*20)) { + if (VM_OBJECT_SLEEP(mreq, object, PSWP, "swread", hz * 20)) { printf( "swap_pager: indefinite wait buffer: bufobj: %p, blkno: %jd, size: %ld\n", bp->b_bufobj, (intmax_t)bp->b_blkno, bp->b_bcount); @@ -1284,7 +1285,7 @@ swap_pager_putpages(vm_object_t object, vm_page_t */ if (object->type != OBJT_SWAP) swp_pager_meta_build(object, 0, SWAPBLK_NONE); - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); if (curproc != pageproc) sync = TRUE; @@ -1379,7 +1380,7 @@ swap_pager_putpages(vm_object_t object, vm_page_t bp->b_bufsize = PAGE_SIZE * n; bp->b_blkno = blk; - VM_OBJECT_LOCK(object); + VM_OBJECT_WLOCK(object); for (j = 0; j < n; ++j) { vm_page_t mreq = m[i+j]; @@ -1394,7 +1395,7 @@ swap_pager_putpages(vm_object_t object, vm_page_t mreq->oflags |= VPO_SWAPINPROG; bp->b_pages[j] = mreq; } - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); bp->b_npages = n; /* * Must set dirty range for NFS to work. @@ -1444,7 +1445,7 @@ swap_pager_putpages(vm_object_t object, vm_page_t */ swp_pager_async_iodone(bp); } - VM_OBJECT_LOCK(object); + VM_OBJECT_WLOCK(object); } /* @@ -1488,7 +1489,7 @@ swp_pager_async_iodone(struct buf *bp) if (bp->b_npages) { object = bp->b_pages[0]->object; - VM_OBJECT_LOCK(object); + VM_OBJECT_WLOCK(object); } /* @@ -1612,7 +1613,7 @@ swp_pager_async_iodone(struct buf *bp) */ if (object != NULL) { vm_object_pip_wakeupn(object, bp->b_npages); - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); } /* @@ -1653,7 +1654,7 @@ swap_pager_isswapped(vm_object_t object, struct sw int bcount; int i; - VM_OBJECT_LOCK_ASSERT(object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(object, RA_WLOCKED); if (object->type != OBJT_SWAP) return (0); @@ -1747,13 +1748,13 @@ restart: for (j = 0; j < SWAP_META_PAGES; ++j) { if (swp_pager_isondev(swap->swb_pages[j], sp)) { /* avoid deadlock */ - if (!VM_OBJECT_TRYLOCK(object)) { + if (!VM_OBJECT_TRYWLOCK(object)) { break; } else { mtx_unlock(&swhash_mtx); swp_pager_force_pagein(object, pindex + j); - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); mtx_lock(&swhash_mtx); goto restart; } @@ -1809,7 +1810,7 @@ swp_pager_meta_build(vm_object_t object, vm_pindex struct swblock **pswap; int idx; - VM_OBJECT_LOCK_ASSERT(object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(object, RA_WLOCKED); /* * Convert default object to swap object if necessary */ @@ -1846,7 +1847,7 @@ retry: swap = *pswap = uma_zalloc(swap_zone, M_NOWAIT); if (swap == NULL) { mtx_unlock(&swhash_mtx); - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); if (uma_zone_exhausted(swap_zone)) { if (atomic_cmpset_int(&exhausted, 0, 1)) printf("swap zone exhausted, " @@ -1855,7 +1856,7 @@ retry: pause("swzonex", 10); } else VM_WAIT; - VM_OBJECT_LOCK(object); + VM_OBJECT_WLOCK(object); goto retry; } @@ -1907,7 +1908,7 @@ static void swp_pager_meta_free(vm_object_t object, vm_pindex_t index, daddr_t count) { - VM_OBJECT_LOCK_ASSERT(object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(object, RA_WLOCKED); if (object->type != OBJT_SWAP) return; @@ -1953,7 +1954,7 @@ swp_pager_meta_free_all(vm_object_t object) { daddr_t index = 0; - VM_OBJECT_LOCK_ASSERT(object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(object, RA_WLOCKED); if (object->type != OBJT_SWAP) return; @@ -2012,7 +2013,7 @@ swp_pager_meta_ctl(vm_object_t object, vm_pindex_t daddr_t r1; int idx; - VM_OBJECT_LOCK_ASSERT(object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(object, RA_WLOCKED); /* * The meta data only exists of the object is OBJT_SWAP * and even then might not be allocated yet. @@ -2465,14 +2466,14 @@ vmspace_swap_count(struct vmspace *vmspace) for (cur = map->header.next; cur != &map->header; cur = cur->next) { if ((cur->eflags & MAP_ENTRY_IS_SUB_MAP) == 0 && (object = cur->object.vm_object) != NULL) { - VM_OBJECT_LOCK(object); + VM_OBJECT_WLOCK(object); if (object->type == OBJT_SWAP && object->un_pager.swp.swp_bcount != 0) { n = (cur->end - cur->start) / PAGE_SIZE; count += object->un_pager.swp.swp_bcount * SWAP_META_PAGES * n / object->size + 1; } - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); } } return (count); Index: vm/vnode_pager.c =================================================================== --- vm/vnode_pager.c (.../head/sys) (revision 247097) +++ vm/vnode_pager.c (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -63,6 +63,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -109,14 +110,14 @@ vnode_create_vobject(struct vnode *vp, off_t isize return (0); while ((object = vp->v_object) != NULL) { - VM_OBJECT_LOCK(object); + VM_OBJECT_WLOCK(object); if (!(object->flags & OBJ_DEAD)) { - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); return (0); } VOP_UNLOCK(vp, 0); vm_object_set_flag(object, OBJ_DISCONNECTWNT); - msleep(object, VM_OBJECT_MTX(object), PDROP | PVM, "vodead", 0); + VM_OBJECT_SLEEP(object, object, PDROP | PVM, "vodead" , 0); vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); } @@ -135,9 +136,9 @@ vnode_create_vobject(struct vnode *vp, off_t isize * Dereference the reference we just created. This assumes * that the object is associated with the vp. */ - VM_OBJECT_LOCK(object); + VM_OBJECT_WLOCK(object); object->ref_count--; - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); vrele(vp); KASSERT(vp->v_object != NULL, ("vnode_create_vobject: NULL object")); @@ -154,7 +155,7 @@ vnode_destroy_vobject(struct vnode *vp) if (obj == NULL) return; ASSERT_VOP_ELOCKED(vp, "vnode_destroy_vobject"); - VM_OBJECT_LOCK(obj); + VM_OBJECT_WLOCK(obj); if (obj->ref_count == 0) { /* * vclean() may be called twice. The first time @@ -167,13 +168,13 @@ vnode_destroy_vobject(struct vnode *vp) if ((obj->flags & OBJ_DEAD) == 0) vm_object_terminate(obj); else - VM_OBJECT_UNLOCK(obj); + VM_OBJECT_WUNLOCK(obj); } else { /* * Woe to the process that tries to page now :-). */ vm_pager_deallocate(obj); - VM_OBJECT_UNLOCK(obj); + VM_OBJECT_WUNLOCK(obj); } vp->v_object = NULL; } @@ -206,11 +207,11 @@ vnode_pager_alloc(void *handle, vm_ooffset_t size, */ retry: while ((object = vp->v_object) != NULL) { - VM_OBJECT_LOCK(object); + VM_OBJECT_WLOCK(object); if ((object->flags & OBJ_DEAD) == 0) break; vm_object_set_flag(object, OBJ_DISCONNECTWNT); - msleep(object, VM_OBJECT_MTX(object), PDROP | PVM, "vadead", 0); + VM_OBJECT_SLEEP(object, object, PDROP | PVM, "vadead" , 0); } if (vp->v_usecount == 0) @@ -239,7 +240,7 @@ retry: VI_UNLOCK(vp); } else { object->ref_count++; - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); } vref(vp); return (object); @@ -259,7 +260,7 @@ vnode_pager_dealloc(object) if (vp == NULL) panic("vnode_pager_dealloc: pager already dealloced"); - VM_OBJECT_LOCK_ASSERT(object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(object, RA_WLOCKED); vm_object_pip_wait(object, "vnpdea"); refs = object->ref_count; @@ -278,10 +279,10 @@ vnode_pager_dealloc(object) } vp->v_object = NULL; VOP_UNSET_TEXT(vp); - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); while (refs-- > 0) vunref(vp); - VM_OBJECT_LOCK(object); + VM_OBJECT_WLOCK(object); } static boolean_t @@ -299,7 +300,7 @@ vnode_pager_haspage(object, pindex, before, after) int bsize; int pagesperblock, blocksperpage; - VM_OBJECT_LOCK_ASSERT(object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(object, RA_WLOCKED); /* * If no vp or vp is doomed or marked transparent to VM, we do not * have the page. @@ -322,9 +323,9 @@ vnode_pager_haspage(object, pindex, before, after) blocksperpage = (PAGE_SIZE / bsize); reqblock = pindex * blocksperpage; } - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); err = VOP_BMAP(vp, reqblock, NULL, &bn, after, before); - VM_OBJECT_LOCK(object); + VM_OBJECT_WLOCK(object); if (err) return TRUE; if (bn == -1) @@ -379,12 +380,12 @@ vnode_pager_setsize(vp, nsize) if ((object = vp->v_object) == NULL) return; /* ASSERT_VOP_ELOCKED(vp, "vnode_pager_setsize and not locked vnode"); */ - VM_OBJECT_LOCK(object); + VM_OBJECT_WLOCK(object); if (nsize == object->un_pager.vnp.vnp_size) { /* * Hasn't changed size */ - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); return; } nobjsize = OFF_TO_IDX(nsize + PAGE_MASK); @@ -445,7 +446,7 @@ vnode_pager_setsize(vp, nsize) } object->un_pager.vnp.vnp_size = nsize; object->size = nobjsize; - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); } /* @@ -568,9 +569,9 @@ vnode_pager_input_smlfs(object, m) bzero((caddr_t)sf_buf_kva(sf) + i * bsize, bsize); KASSERT((m->dirty & bits) == 0, ("vnode_pager_input_smlfs: page %p is dirty", m)); - VM_OBJECT_LOCK(object); + VM_OBJECT_WLOCK(object); m->valid |= bits; - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); } sf_buf_free(sf); if (error) { @@ -594,7 +595,7 @@ vnode_pager_input_old(object, m) struct sf_buf *sf; struct vnode *vp; - VM_OBJECT_LOCK_ASSERT(object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(object, RA_WLOCKED); error = 0; /* @@ -607,7 +608,7 @@ vnode_pager_input_old(object, m) if (IDX_TO_OFF(m->pindex) + size > object->un_pager.vnp.vnp_size) size = object->un_pager.vnp.vnp_size - IDX_TO_OFF(m->pindex); vp = object->handle; - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); /* * Allocate a kernel virtual address and initialize so that @@ -637,7 +638,7 @@ vnode_pager_input_old(object, m) } sf_buf_free(sf); - VM_OBJECT_LOCK(object); + VM_OBJECT_WLOCK(object); } KASSERT(m->dirty == 0, ("vnode_pager_input_old: page %p is dirty", m)); if (!error) @@ -669,11 +670,11 @@ vnode_pager_getpages(object, m, count, reqpage) int bytes = count * PAGE_SIZE; vp = object->handle; - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); rtval = VOP_GETPAGES(vp, m, bytes, reqpage, 0); KASSERT(rtval != EOPNOTSUPP, ("vnode_pager: FS getpages not implemented\n")); - VM_OBJECT_LOCK(object); + VM_OBJECT_WLOCK(object); return rtval; } @@ -723,7 +724,7 @@ vnode_pager_generic_getpages(vp, m, bytecount, req */ error = VOP_BMAP(vp, foff / bsize, &bo, &reqblock, NULL, NULL); if (error == EOPNOTSUPP) { - VM_OBJECT_LOCK(object); + VM_OBJECT_WLOCK(object); for (i = 0; i < count; i++) if (i != reqpage) { @@ -734,17 +735,17 @@ vnode_pager_generic_getpages(vp, m, bytecount, req PCPU_INC(cnt.v_vnodein); PCPU_INC(cnt.v_vnodepgsin); error = vnode_pager_input_old(object, m[reqpage]); - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); return (error); } else if (error != 0) { - VM_OBJECT_LOCK(object); + VM_OBJECT_WLOCK(object); for (i = 0; i < count; i++) if (i != reqpage) { vm_page_lock(m[i]); vm_page_free(m[i]); vm_page_unlock(m[i]); } - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); return (VM_PAGER_ERROR); /* @@ -754,14 +755,14 @@ vnode_pager_generic_getpages(vp, m, bytecount, req */ } else if ((PAGE_SIZE / bsize) > 1 && (vp->v_mount->mnt_stat.f_type != nfs_mount_type)) { - VM_OBJECT_LOCK(object); + VM_OBJECT_WLOCK(object); for (i = 0; i < count; i++) if (i != reqpage) { vm_page_lock(m[i]); vm_page_free(m[i]); vm_page_unlock(m[i]); } - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); PCPU_INC(cnt.v_vnodein); PCPU_INC(cnt.v_vnodepgsin); return vnode_pager_input_smlfs(object, m[reqpage]); @@ -772,7 +773,7 @@ vnode_pager_generic_getpages(vp, m, bytecount, req * clean up and return. Otherwise we have to re-read the * media. */ - VM_OBJECT_LOCK(object); + VM_OBJECT_WLOCK(object); if (m[reqpage]->valid == VM_PAGE_BITS_ALL) { for (i = 0; i < count; i++) if (i != reqpage) { @@ -780,7 +781,7 @@ vnode_pager_generic_getpages(vp, m, bytecount, req vm_page_free(m[i]); vm_page_unlock(m[i]); } - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); return VM_PAGER_OK; } else if (reqblock == -1) { pmap_zero_page(m[reqpage]); @@ -793,11 +794,11 @@ vnode_pager_generic_getpages(vp, m, bytecount, req vm_page_free(m[i]); vm_page_unlock(m[i]); } - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); return (VM_PAGER_OK); } m[reqpage]->valid = 0; - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); /* * here on direct device I/O @@ -810,18 +811,18 @@ vnode_pager_generic_getpages(vp, m, bytecount, req for (first = 0, i = 0; i < count; i = runend) { if (vnode_pager_addr(vp, IDX_TO_OFF(m[i]->pindex), &firstaddr, &runpg) != 0) { - VM_OBJECT_LOCK(object); + VM_OBJECT_WLOCK(object); for (; i < count; i++) if (i != reqpage) { vm_page_lock(m[i]); vm_page_free(m[i]); vm_page_unlock(m[i]); } - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); return (VM_PAGER_ERROR); } if (firstaddr == -1) { - VM_OBJECT_LOCK(object); + VM_OBJECT_WLOCK(object); if (i == reqpage && foff < object->un_pager.vnp.vnp_size) { panic("vnode_pager_getpages: unexpected missing page: firstaddr: %jd, foff: 0x%jx%08jx, vnp_size: 0x%jx%08jx", (intmax_t)firstaddr, (uintmax_t)(foff >> 32), @@ -833,29 +834,29 @@ vnode_pager_generic_getpages(vp, m, bytecount, req vm_page_lock(m[i]); vm_page_free(m[i]); vm_page_unlock(m[i]); - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); runend = i + 1; first = runend; continue; } runend = i + runpg; if (runend <= reqpage) { - VM_OBJECT_LOCK(object); + VM_OBJECT_WLOCK(object); for (j = i; j < runend; j++) { vm_page_lock(m[j]); vm_page_free(m[j]); vm_page_unlock(m[j]); } - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); } else { if (runpg < (count - first)) { - VM_OBJECT_LOCK(object); + VM_OBJECT_WLOCK(object); for (i = first + runpg; i < count; i++) { vm_page_lock(m[i]); vm_page_free(m[i]); vm_page_unlock(m[i]); } - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); count = first + runpg; } break; @@ -946,7 +947,7 @@ vnode_pager_generic_getpages(vp, m, bytecount, req pbrelbo(bp); relpbuf(bp, &vnode_pbuf_freecnt); - VM_OBJECT_LOCK(object); + VM_OBJECT_WLOCK(object); for (i = 0, tfoff = foff; i < count; i++, tfoff = nextoff) { vm_page_t mt; @@ -983,7 +984,7 @@ vnode_pager_generic_getpages(vp, m, bytecount, req if (i != reqpage) vm_page_readahead_finish(mt); } - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); if (error) { printf("vnode_pager_getpages: I/O read error\n"); } @@ -1029,11 +1030,11 @@ vnode_pager_putpages(object, m, count, sync, rtval * Call device-specific putpages function */ vp = object->handle; - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); rtval = VOP_PUTPAGES(vp, m, bytes, sync, rtvals, 0); KASSERT(rtval != EOPNOTSUPP, ("vnode_pager: stale FS putpages\n")); - VM_OBJECT_LOCK(object); + VM_OBJECT_WLOCK(object); } @@ -1095,7 +1096,7 @@ vnode_pager_generic_putpages(struct vnode *vp, vm_ * We do not under any circumstances truncate the valid bits, as * this will screw up bogus page replacement. */ - VM_OBJECT_LOCK(object); + VM_OBJECT_WLOCK(object); if (maxsize + poffset > object->un_pager.vnp.vnp_size) { if (object->un_pager.vnp.vnp_size > poffset) { int pgoff; @@ -1127,7 +1128,7 @@ vnode_pager_generic_putpages(struct vnode *vp, vm_ } } } - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); /* * pageouts are already clustered, use IO_ASYNC to force a bawrite() @@ -1181,7 +1182,7 @@ vnode_pager_undirty_pages(vm_page_t *ma, int *rtva if (written == 0) return; obj = ma[0]->object; - VM_OBJECT_LOCK(obj); + VM_OBJECT_WLOCK(obj); for (i = 0, pos = 0; pos < written; i++, pos += PAGE_SIZE) { if (pos < trunc_page(written)) { rtvals[i] = VM_PAGER_OK; @@ -1192,7 +1193,7 @@ vnode_pager_undirty_pages(vm_page_t *ma, int *rtva vm_page_clear_dirty(ma[i], 0, written & PAGE_MASK); } } - VM_OBJECT_UNLOCK(obj); + VM_OBJECT_WUNLOCK(obj); } void @@ -1202,9 +1203,9 @@ vnode_pager_update_writecount(vm_object_t object, struct vnode *vp; vm_ooffset_t old_wm; - VM_OBJECT_LOCK(object); + VM_OBJECT_WLOCK(object); if (object->type != OBJT_VNODE) { - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); return; } old_wm = object->un_pager.vnp.writemappings; @@ -1221,7 +1222,7 @@ vnode_pager_update_writecount(vm_object_t object, CTR3(KTR_VFS, "%s: vp %p v_writecount decreased to %d", __func__, vp, vp->v_writecount); } - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); } void @@ -1232,14 +1233,14 @@ vnode_pager_release_writecount(vm_object_t object, struct mount *mp; vm_offset_t inc; - VM_OBJECT_LOCK(object); + VM_OBJECT_WLOCK(object); /* * First, recheck the object type to account for the race when * the vnode is reclaimed. */ if (object->type != OBJT_VNODE) { - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); return; } @@ -1250,13 +1251,13 @@ vnode_pager_release_writecount(vm_object_t object, inc = end - start; if (object->un_pager.vnp.writemappings != inc) { object->un_pager.vnp.writemappings -= inc; - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); return; } vp = object->handle; vhold(vp); - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); mp = NULL; vn_start_write(vp, &mp, V_WAIT); vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); Index: vm/vm_kern.c =================================================================== --- vm/vm_kern.c (.../head/sys) (revision 247097) +++ vm/vm_kern.c (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -70,9 +70,9 @@ __FBSDID("$FreeBSD$"); #include /* for ticks and hz */ #include #include -#include #include #include +#include #include #include @@ -234,7 +234,7 @@ kmem_alloc_attr(vm_map_t map, vm_size_t size, int vm_map_insert(map, object, offset, addr, addr + size, VM_PROT_ALL, VM_PROT_ALL, 0); pflags = malloc2vm_flags(flags) | VM_ALLOC_NOBUSY; - VM_OBJECT_LOCK(object); + VM_OBJECT_WLOCK(object); end_offset = offset + size; for (; offset < end_offset; offset += PAGE_SIZE) { tries = 0; @@ -242,12 +242,12 @@ retry: m = vm_page_alloc_contig(object, OFF_TO_IDX(offset), pflags, 1, low, high, PAGE_SIZE, 0, memattr); if (m == NULL) { - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); if (tries < ((flags & M_NOWAIT) != 0 ? 1 : 3)) { vm_map_unlock(map); vm_pageout_grow_cache(tries, low, high); vm_map_lock(map); - VM_OBJECT_LOCK(object); + VM_OBJECT_WLOCK(object); tries++; goto retry; } @@ -266,7 +266,7 @@ retry: pmap_zero_page(m); m->valid = VM_PAGE_BITS_ALL; } - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); vm_map_unlock(map); vm_map_wire(map, addr, addr + size, VM_MAP_WIRE_SYSTEM | VM_MAP_WIRE_NOHOLES); @@ -303,18 +303,18 @@ kmem_alloc_contig(vm_map_t map, vm_size_t size, in vm_map_insert(map, object, offset, addr, addr + size, VM_PROT_ALL, VM_PROT_ALL, 0); pflags = malloc2vm_flags(flags) | VM_ALLOC_NOBUSY; - VM_OBJECT_LOCK(object); + VM_OBJECT_WLOCK(object); tries = 0; retry: m = vm_page_alloc_contig(object, OFF_TO_IDX(offset), pflags, atop(size), low, high, alignment, boundary, memattr); if (m == NULL) { - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); if (tries < ((flags & M_NOWAIT) != 0 ? 1 : 3)) { vm_map_unlock(map); vm_pageout_grow_cache(tries, low, high); vm_map_lock(map); - VM_OBJECT_LOCK(object); + VM_OBJECT_WLOCK(object); tries++; goto retry; } @@ -328,7 +328,7 @@ retry: pmap_zero_page(m); m->valid = VM_PAGE_BITS_ALL; } - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); vm_map_unlock(map); vm_map_wire(map, addr, addr + size, VM_MAP_WIRE_SYSTEM | VM_MAP_WIRE_NOHOLES); @@ -488,7 +488,7 @@ kmem_back(vm_map_t map, vm_offset_t addr, vm_size_ pflags = malloc2vm_flags(flags) | VM_ALLOC_WIRED; - VM_OBJECT_LOCK(kmem_object); + VM_OBJECT_WLOCK(kmem_object); for (i = 0; i < size; i += PAGE_SIZE) { retry: m = vm_page_alloc(kmem_object, OFF_TO_IDX(offset + i), pflags); @@ -500,7 +500,7 @@ retry: */ if (m == NULL) { if ((flags & M_NOWAIT) == 0) { - VM_OBJECT_UNLOCK(kmem_object); + VM_OBJECT_WUNLOCK(kmem_object); entry->eflags |= MAP_ENTRY_IN_TRANSITION; vm_map_unlock(map); VM_WAIT; @@ -510,7 +510,7 @@ retry: MAP_ENTRY_IN_TRANSITION, ("kmem_back: volatile entry")); entry->eflags &= ~MAP_ENTRY_IN_TRANSITION; - VM_OBJECT_LOCK(kmem_object); + VM_OBJECT_WLOCK(kmem_object); goto retry; } /* @@ -526,7 +526,7 @@ retry: vm_page_unwire(m, 0); vm_page_free(m); } - VM_OBJECT_UNLOCK(kmem_object); + VM_OBJECT_WUNLOCK(kmem_object); vm_map_delete(map, addr, addr + size); return (KERN_NO_SPACE); } @@ -536,7 +536,7 @@ retry: KASSERT((m->oflags & VPO_UNMANAGED) != 0, ("kmem_malloc: page %p is managed", m)); } - VM_OBJECT_UNLOCK(kmem_object); + VM_OBJECT_WUNLOCK(kmem_object); /* * Mark map entry as non-pageable. Repeat the assert. @@ -556,7 +556,7 @@ retry: /* * Loop thru pages, entering them in the pmap. */ - VM_OBJECT_LOCK(kmem_object); + VM_OBJECT_WLOCK(kmem_object); for (i = 0; i < size; i += PAGE_SIZE) { m = vm_page_lookup(kmem_object, OFF_TO_IDX(offset + i)); /* @@ -566,7 +566,7 @@ retry: TRUE); vm_page_wakeup(m); } - VM_OBJECT_UNLOCK(kmem_object); + VM_OBJECT_WUNLOCK(kmem_object); return (KERN_SUCCESS); } Index: vm/default_pager.c =================================================================== --- vm/default_pager.c (.../head/sys) (revision 247097) +++ vm/default_pager.c (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -45,7 +45,7 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include +#include #include #include @@ -91,10 +91,10 @@ default_pager_alloc(void *handle, vm_ooffset_t siz object = vm_object_allocate(OBJT_DEFAULT, OFF_TO_IDX(round_page(offset + size))); if (cred != NULL) { - VM_OBJECT_LOCK(object); + VM_OBJECT_WLOCK(object); object->cred = cred; object->charge = size; - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); } return (object); } Index: vm/vm_fault.c =================================================================== --- vm/vm_fault.c (.../head/sys) (revision 247097) +++ vm/vm_fault.c (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -81,9 +81,9 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include #include +#include #include #include #include @@ -163,14 +163,14 @@ unlock_and_deallocate(struct faultstate *fs) { vm_object_pip_wakeup(fs->object); - VM_OBJECT_UNLOCK(fs->object); + VM_OBJECT_WUNLOCK(fs->object); if (fs->object != fs->first_object) { - VM_OBJECT_LOCK(fs->first_object); + VM_OBJECT_WLOCK(fs->first_object); vm_page_lock(fs->first_m); vm_page_free(fs->first_m); vm_page_unlock(fs->first_m); vm_object_pip_wakeup(fs->first_object); - VM_OBJECT_UNLOCK(fs->first_object); + VM_OBJECT_WUNLOCK(fs->first_object); fs->first_m = NULL; } vm_object_deallocate(fs->first_object); @@ -290,7 +290,7 @@ RetryFault:; * truncation operations) during I/O. This must be done after * obtaining the vnode lock in order to avoid possible deadlocks. */ - VM_OBJECT_LOCK(fs.first_object); + VM_OBJECT_WLOCK(fs.first_object); vm_object_reference_locked(fs.first_object); vm_object_pip_add(fs.first_object, 1); @@ -363,17 +363,17 @@ RetryFault:; vm_page_aflag_set(fs.m, PGA_REFERENCED); vm_page_unlock(fs.m); if (fs.object != fs.first_object) { - if (!VM_OBJECT_TRYLOCK( + if (!VM_OBJECT_TRYWLOCK( fs.first_object)) { - VM_OBJECT_UNLOCK(fs.object); - VM_OBJECT_LOCK(fs.first_object); - VM_OBJECT_LOCK(fs.object); + VM_OBJECT_WUNLOCK(fs.object); + VM_OBJECT_WLOCK(fs.first_object); + VM_OBJECT_WLOCK(fs.object); } vm_page_lock(fs.first_m); vm_page_free(fs.first_m); vm_page_unlock(fs.first_m); vm_object_pip_wakeup(fs.first_object); - VM_OBJECT_UNLOCK(fs.first_object); + VM_OBJECT_WUNLOCK(fs.first_object); fs.first_m = NULL; } unlock_map(&fs); @@ -383,7 +383,7 @@ RetryFault:; "vmpfw"); } vm_object_pip_wakeup(fs.object); - VM_OBJECT_UNLOCK(fs.object); + VM_OBJECT_WUNLOCK(fs.object); PCPU_INC(cnt.v_intrans); vm_object_deallocate(fs.first_object); goto RetryFault; @@ -646,12 +646,12 @@ vnode_locked: */ if (fs.object != fs.first_object) { vm_object_pip_wakeup(fs.object); - VM_OBJECT_UNLOCK(fs.object); + VM_OBJECT_WUNLOCK(fs.object); fs.object = fs.first_object; fs.pindex = fs.first_pindex; fs.m = fs.first_m; - VM_OBJECT_LOCK(fs.object); + VM_OBJECT_WLOCK(fs.object); } fs.first_m = NULL; @@ -669,11 +669,11 @@ vnode_locked: } else { KASSERT(fs.object != next_object, ("object loop %p", next_object)); - VM_OBJECT_LOCK(next_object); + VM_OBJECT_WLOCK(next_object); vm_object_pip_add(next_object, 1); if (fs.object != fs.first_object) vm_object_pip_wakeup(fs.object); - VM_OBJECT_UNLOCK(fs.object); + VM_OBJECT_WUNLOCK(fs.object); fs.object = next_object; } } @@ -725,7 +725,7 @@ vnode_locked: */ ((fs.object->type == OBJT_DEFAULT) || (fs.object->type == OBJT_SWAP)) && - (is_first_object_locked = VM_OBJECT_TRYLOCK(fs.first_object)) && + (is_first_object_locked = VM_OBJECT_TRYWLOCK(fs.first_object)) && /* * We don't chase down the shadow chain */ @@ -774,7 +774,7 @@ vnode_locked: * conditional */ vm_object_pip_wakeup(fs.object); - VM_OBJECT_UNLOCK(fs.object); + VM_OBJECT_WUNLOCK(fs.object); /* * Only use the new page below... */ @@ -782,7 +782,7 @@ vnode_locked: fs.pindex = fs.first_pindex; fs.m = fs.first_m; if (!is_first_object_locked) - VM_OBJECT_LOCK(fs.object); + VM_OBJECT_WLOCK(fs.object); PCPU_INC(cnt.v_cow_faults); curthread->td_cow++; } else { @@ -903,7 +903,7 @@ vnode_locked: */ KASSERT(fs.m->valid == VM_PAGE_BITS_ALL, ("vm_fault: page %p partially invalid", fs.m)); - VM_OBJECT_UNLOCK(fs.object); + VM_OBJECT_WUNLOCK(fs.object); /* * Put this page into the physical map. We had to do the unlock above @@ -914,7 +914,7 @@ vnode_locked: pmap_enter(fs.map->pmap, vaddr, fault_type, fs.m, prot, wired); if ((fault_flags & VM_FAULT_CHANGE_WIRING) == 0 && wired == 0) vm_fault_prefault(fs.map->pmap, vaddr, fs.entry); - VM_OBJECT_LOCK(fs.object); + VM_OBJECT_WLOCK(fs.object); vm_page_lock(fs.m); /* @@ -960,13 +960,13 @@ vm_fault_cache_behind(const struct faultstate *fs, vm_pindex_t pindex; object = fs->object; - VM_OBJECT_LOCK_ASSERT(object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(object, RA_WLOCKED); first_object = fs->first_object; if (first_object != object) { - if (!VM_OBJECT_TRYLOCK(first_object)) { - VM_OBJECT_UNLOCK(object); - VM_OBJECT_LOCK(first_object); - VM_OBJECT_LOCK(object); + if (!VM_OBJECT_TRYWLOCK(first_object)) { + VM_OBJECT_WUNLOCK(object); + VM_OBJECT_WLOCK(first_object); + VM_OBJECT_WLOCK(object); } } /* Neither fictitious nor unmanaged pages can be cached. */ @@ -999,7 +999,7 @@ vm_fault_cache_behind(const struct faultstate *fs, } } if (first_object != object) - VM_OBJECT_UNLOCK(first_object); + VM_OBJECT_WUNLOCK(first_object); } /* @@ -1044,28 +1044,28 @@ vm_fault_prefault(pmap_t pmap, vm_offset_t addra, pindex = ((addr - entry->start) + entry->offset) >> PAGE_SHIFT; lobject = object; - VM_OBJECT_LOCK(lobject); + VM_OBJECT_WLOCK(lobject); while ((m = vm_page_lookup(lobject, pindex)) == NULL && lobject->type == OBJT_DEFAULT && (backing_object = lobject->backing_object) != NULL) { KASSERT((lobject->backing_object_offset & PAGE_MASK) == 0, ("vm_fault_prefault: unaligned object offset")); pindex += lobject->backing_object_offset >> PAGE_SHIFT; - VM_OBJECT_LOCK(backing_object); - VM_OBJECT_UNLOCK(lobject); + VM_OBJECT_WLOCK(backing_object); + VM_OBJECT_WUNLOCK(lobject); lobject = backing_object; } /* * give-up when a page is not in memory */ if (m == NULL) { - VM_OBJECT_UNLOCK(lobject); + VM_OBJECT_WUNLOCK(lobject); break; } if (m->valid == VM_PAGE_BITS_ALL && (m->flags & PG_FICTITIOUS) == 0) pmap_enter_quick(pmap, addr, m, entry->protection); - VM_OBJECT_UNLOCK(lobject); + VM_OBJECT_WUNLOCK(lobject); } } @@ -1257,7 +1257,7 @@ vm_fault_copy_entry(vm_map_t dst_map, vm_map_t src dst_object->pg_color = atop(dst_entry->start); #endif - VM_OBJECT_LOCK(dst_object); + VM_OBJECT_WLOCK(dst_object); KASSERT(upgrade || dst_entry->object.vm_object == NULL, ("vm_fault_copy_entry: vm_object not NULL")); dst_entry->object.vm_object = dst_object; @@ -1307,9 +1307,9 @@ vm_fault_copy_entry(vm_map_t dst_map, vm_map_t src dst_m = vm_page_alloc(dst_object, dst_pindex, VM_ALLOC_NORMAL); if (dst_m == NULL) { - VM_OBJECT_UNLOCK(dst_object); + VM_OBJECT_WUNLOCK(dst_object); VM_WAIT; - VM_OBJECT_LOCK(dst_object); + VM_OBJECT_WLOCK(dst_object); } } while (dst_m == NULL); @@ -1318,7 +1318,7 @@ vm_fault_copy_entry(vm_map_t dst_map, vm_map_t src * (Because the source is wired down, the page will be in * memory.) */ - VM_OBJECT_LOCK(src_object); + VM_OBJECT_WLOCK(src_object); object = src_object; pindex = src_pindex + dst_pindex; while ((src_m = vm_page_lookup(object, pindex)) == NULL && @@ -1327,18 +1327,18 @@ vm_fault_copy_entry(vm_map_t dst_map, vm_map_t src /* * Allow fallback to backing objects if we are reading. */ - VM_OBJECT_LOCK(backing_object); + VM_OBJECT_WLOCK(backing_object); pindex += OFF_TO_IDX(object->backing_object_offset); - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); object = backing_object; } if (src_m == NULL) panic("vm_fault_copy_wired: page missing"); pmap_copy_page(src_m, dst_m); - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); dst_m->valid = VM_PAGE_BITS_ALL; dst_m->dirty = VM_PAGE_BITS_ALL; - VM_OBJECT_UNLOCK(dst_object); + VM_OBJECT_WUNLOCK(dst_object); /* * Enter it in the pmap. If a wired, copy-on-write @@ -1350,7 +1350,7 @@ vm_fault_copy_entry(vm_map_t dst_map, vm_map_t src /* * Mark it no longer busy, and put it on the active list. */ - VM_OBJECT_LOCK(dst_object); + VM_OBJECT_WLOCK(dst_object); if (upgrade) { vm_page_lock(src_m); @@ -1367,7 +1367,7 @@ vm_fault_copy_entry(vm_map_t dst_map, vm_map_t src } vm_page_wakeup(dst_m); } - VM_OBJECT_UNLOCK(dst_object); + VM_OBJECT_WUNLOCK(dst_object); if (upgrade) { dst_entry->eflags &= ~(MAP_ENTRY_COW | MAP_ENTRY_NEEDS_COPY); vm_object_deallocate(src_object); @@ -1403,7 +1403,7 @@ vm_fault_additional_pages(m, rbehind, rahead, marr vm_page_t rtm; int cbehind, cahead; - VM_OBJECT_LOCK_ASSERT(m->object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(m->object, RA_WLOCKED); object = m->object; pindex = m->pindex; Index: vm/device_pager.c =================================================================== --- vm/device_pager.c (.../head/sys) (revision 247097) +++ vm/device_pager.c (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -44,6 +44,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -206,7 +207,7 @@ void cdev_pager_free_page(vm_object_t object, vm_page_t m) { - VM_OBJECT_LOCK_ASSERT(object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(object, RA_WLOCKED); if (object->type == OBJT_MGTDEVICE) { KASSERT((m->oflags & VPO_UNMANAGED) == 0, ("unmanaged %p", m)); pmap_remove_all(m); @@ -221,7 +222,7 @@ static void dev_pager_free_page(vm_object_t object, vm_page_t m) { - VM_OBJECT_LOCK_ASSERT(object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(object, RA_WLOCKED); KASSERT((object->type == OBJT_DEVICE && (m->oflags & VPO_UNMANAGED) != 0), ("Managed device or page obj %p m %p", object, m)); @@ -235,13 +236,13 @@ dev_pager_dealloc(object) { vm_page_t m; - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); object->un_pager.devp.ops->cdev_pg_dtor(object->un_pager.devp.dev); mtx_lock(&dev_pager_mtx); TAILQ_REMOVE(&dev_pager_object_list, object, pager_object_list); mtx_unlock(&dev_pager_mtx); - VM_OBJECT_LOCK(object); + VM_OBJECT_WLOCK(object); if (object->type == OBJT_DEVICE) { /* @@ -258,11 +259,11 @@ dev_pager_getpages(vm_object_t object, vm_page_t * { int error, i; - VM_OBJECT_LOCK_ASSERT(object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(object, RA_WLOCKED); error = object->un_pager.devp.ops->cdev_pg_fault(object, IDX_TO_OFF(ma[reqpage]->pindex), PROT_READ, &ma[reqpage]); - VM_OBJECT_LOCK_ASSERT(object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(object, RA_WLOCKED); for (i = 0; i < count; i++) { if (i != reqpage) { @@ -304,12 +305,12 @@ old_dev_pager_fault(vm_object_t object, vm_ooffset pidx = OFF_TO_IDX(offset); memattr = object->memattr; - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); dev = object->handle; csw = dev_refthread(dev, &ref); if (csw == NULL) { - VM_OBJECT_LOCK(object); + VM_OBJECT_WLOCK(object); return (VM_PAGER_FAIL); } td = curthread; @@ -321,7 +322,7 @@ old_dev_pager_fault(vm_object_t object, vm_ooffset if (ret != 0) { printf( "WARNING: dev_pager_getpage: map function returns error %d", ret); - VM_OBJECT_LOCK(object); + VM_OBJECT_WLOCK(object); return (VM_PAGER_FAIL); } @@ -338,7 +339,7 @@ old_dev_pager_fault(vm_object_t object, vm_ooffset * the new physical address. */ page = *mres; - VM_OBJECT_LOCK(object); + VM_OBJECT_WLOCK(object); vm_page_updatefake(page, paddr, memattr); } else { /* @@ -346,7 +347,7 @@ old_dev_pager_fault(vm_object_t object, vm_ooffset * free up the all of the original pages. */ page = vm_page_getfake(paddr, memattr); - VM_OBJECT_LOCK(object); + VM_OBJECT_WLOCK(object); vm_page_lock(*mres); vm_page_free(*mres); vm_page_unlock(*mres); Index: vm/uma_core.c =================================================================== --- vm/uma_core.c (.../head/sys) (revision 247097) +++ vm/uma_core.c (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -72,6 +72,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -1045,7 +1046,7 @@ obj_alloc(uma_zone_t zone, int bytes, u_int8_t *fl /* * This looks a little weird since we're getting one page at a time. */ - VM_OBJECT_LOCK(object); + VM_OBJECT_WLOCK(object); p = TAILQ_LAST(&object->memq, pglist); pages = p != NULL ? p->pindex + 1 : 0; startpages = pages; @@ -1072,7 +1073,7 @@ obj_alloc(uma_zone_t zone, int bytes, u_int8_t *fl pages += 1; } done: - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); *flags = UMA_SLAB_PRIV; return ((void *)retkva); @@ -3031,7 +3032,7 @@ uma_zone_set_obj(uma_zone_t zone, struct vm_object if (obj == NULL) obj = vm_object_allocate(OBJT_PHYS, pages); else { - VM_OBJECT_LOCK_INIT(obj, "uma object"); + VM_OBJECT_LOCK_INIT(obj, "uma vm object"); _vm_object_allocate(OBJT_PHYS, pages, obj); } ZONE_LOCK(zone); Index: vm/vm_mmap.c =================================================================== --- vm/vm_mmap.c (.../head/sys) (revision 247097) +++ vm/vm_mmap.c (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -59,6 +59,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -880,12 +881,12 @@ RestartScan: m = PHYS_TO_VM_PAGE(locked_pa); if (m->object != object) { if (object != NULL) - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); object = m->object; - locked = VM_OBJECT_TRYLOCK(object); + locked = VM_OBJECT_TRYWLOCK(object); vm_page_unlock(m); if (!locked) { - VM_OBJECT_LOCK(object); + VM_OBJECT_WLOCK(object); vm_page_lock(m); goto retry; } @@ -903,9 +904,9 @@ RestartScan: */ if (current->object.vm_object != object) { if (object != NULL) - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); object = current->object.vm_object; - VM_OBJECT_LOCK(object); + VM_OBJECT_WLOCK(object); } if (object->type == OBJT_DEFAULT || object->type == OBJT_SWAP || @@ -942,7 +943,7 @@ RestartScan: mincoreinfo |= MINCORE_REFERENCED_OTHER; } if (object != NULL) - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); /* * subyte may page fault. In case it needs to modify Index: vm/vm_glue.c =================================================================== --- vm/vm_glue.c (.../head/sys) (revision 247097) +++ vm/vm_glue.c (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -71,6 +71,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -238,7 +239,7 @@ vm_imgact_hold_page(vm_object_t object, vm_ooffset vm_pindex_t pindex; int rv; - VM_OBJECT_LOCK(object); + VM_OBJECT_WLOCK(object); pindex = OFF_TO_IDX(offset); m = vm_page_grab(object, pindex, VM_ALLOC_NORMAL | VM_ALLOC_RETRY); if (m->valid != VM_PAGE_BITS_ALL) { @@ -260,7 +261,7 @@ vm_imgact_hold_page(vm_object_t object, vm_ooffset vm_page_unlock(m); vm_page_wakeup(m); out: - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); return (m); } @@ -394,7 +395,7 @@ vm_thread_new(struct thread *td, int pages) * For the length of the stack, link in a real page of ram for each * page of stack. */ - VM_OBJECT_LOCK(ksobj); + VM_OBJECT_WLOCK(ksobj); for (i = 0; i < pages; i++) { /* * Get a kernel stack page. @@ -404,7 +405,7 @@ vm_thread_new(struct thread *td, int pages) ma[i] = m; m->valid = VM_PAGE_BITS_ALL; } - VM_OBJECT_UNLOCK(ksobj); + VM_OBJECT_WUNLOCK(ksobj); pmap_qenter(ks, ma, pages); return (1); } @@ -417,7 +418,7 @@ vm_thread_stack_dispose(vm_object_t ksobj, vm_offs atomic_add_int(&kstacks, -1); pmap_qremove(ks, pages); - VM_OBJECT_LOCK(ksobj); + VM_OBJECT_WLOCK(ksobj); for (i = 0; i < pages; i++) { m = vm_page_lookup(ksobj, i); if (m == NULL) @@ -427,7 +428,7 @@ vm_thread_stack_dispose(vm_object_t ksobj, vm_offs vm_page_free(m); vm_page_unlock(m); } - VM_OBJECT_UNLOCK(ksobj); + VM_OBJECT_WUNLOCK(ksobj); vm_object_deallocate(ksobj); kmem_free(kernel_map, ks - (KSTACK_GUARD_PAGES * PAGE_SIZE), (pages + KSTACK_GUARD_PAGES) * PAGE_SIZE); @@ -505,7 +506,7 @@ vm_thread_swapout(struct thread *td) pages = td->td_kstack_pages; ksobj = td->td_kstack_obj; pmap_qremove(td->td_kstack, pages); - VM_OBJECT_LOCK(ksobj); + VM_OBJECT_WLOCK(ksobj); for (i = 0; i < pages; i++) { m = vm_page_lookup(ksobj, i); if (m == NULL) @@ -515,7 +516,7 @@ vm_thread_swapout(struct thread *td) vm_page_unwire(m, 0); vm_page_unlock(m); } - VM_OBJECT_UNLOCK(ksobj); + VM_OBJECT_WUNLOCK(ksobj); } /* @@ -530,7 +531,7 @@ vm_thread_swapin(struct thread *td) pages = td->td_kstack_pages; ksobj = td->td_kstack_obj; - VM_OBJECT_LOCK(ksobj); + VM_OBJECT_WLOCK(ksobj); for (i = 0; i < pages; i++) ma[i] = vm_page_grab(ksobj, i, VM_ALLOC_NORMAL | VM_ALLOC_RETRY | VM_ALLOC_WIRED); @@ -557,7 +558,7 @@ vm_thread_swapin(struct thread *td) } else if (ma[i]->oflags & VPO_BUSY) vm_page_wakeup(ma[i]); } - VM_OBJECT_UNLOCK(ksobj); + VM_OBJECT_WUNLOCK(ksobj); pmap_qenter(td->td_kstack, ma, pages); cpu_thread_swapin(td); } Index: vm/vm_pager.c =================================================================== --- vm/vm_pager.c (.../head/sys) (revision 247097) +++ vm/vm_pager.c (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -74,6 +74,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -248,7 +249,7 @@ vm_pager_deallocate(object) vm_object_t object; { - VM_OBJECT_LOCK_ASSERT(object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(object, RA_WLOCKED); (*pagertab[object->type]->pgo_dealloc) (object); } @@ -272,13 +273,13 @@ vm_pager_object_lookup(struct pagerlst *pg_list, v TAILQ_FOREACH(object, pg_list, pager_object_list) { if (object->handle == handle) { - VM_OBJECT_LOCK(object); + VM_OBJECT_WLOCK(object); if ((object->flags & OBJ_DEAD) == 0) { vm_object_reference_locked(object); - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); break; } - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); } } return (object); Index: vm/phys_pager.c =================================================================== --- vm/phys_pager.c (.../head/sys) (revision 247097) +++ vm/phys_pager.c (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -34,6 +34,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -123,11 +124,11 @@ phys_pager_dealloc(vm_object_t object) { if (object->handle != NULL) { - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); mtx_lock(&phys_pager_mtx); TAILQ_REMOVE(&phys_pager_object_list, object, pager_object_list); mtx_unlock(&phys_pager_mtx); - VM_OBJECT_LOCK(object); + VM_OBJECT_WLOCK(object); } } @@ -139,7 +140,7 @@ phys_pager_getpages(vm_object_t object, vm_page_t { int i; - VM_OBJECT_LOCK_ASSERT(object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(object, RA_WLOCKED); for (i = 0; i < count; i++) { if (m[i]->valid == 0) { if ((m[i]->flags & PG_ZERO) == 0) Index: vm/vm_pager.h =================================================================== --- vm/vm_pager.h (.../head/sys) (revision 247097) +++ vm/vm_pager.h (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -124,7 +124,7 @@ vm_pager_get_pages( ) { int r; - VM_OBJECT_LOCK_ASSERT(object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(object, RA_WLOCKED); r = (*pagertab[object->type]->pgo_getpages)(object, m, count, reqpage); if (r == VM_PAGER_OK && m[reqpage]->valid != VM_PAGE_BITS_ALL) { vm_page_zero_invalid(m[reqpage], TRUE); @@ -141,7 +141,7 @@ vm_pager_put_pages( int *rtvals ) { - VM_OBJECT_LOCK_ASSERT(object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(object, RA_WLOCKED); (*pagertab[object->type]->pgo_putpages) (object, m, count, flags, rtvals); } @@ -165,7 +165,7 @@ vm_pager_has_page( ) { boolean_t ret; - VM_OBJECT_LOCK_ASSERT(object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(object, RA_WLOCKED); ret = (*pagertab[object->type]->pgo_haspage) (object, offset, before, after); return (ret); @@ -188,7 +188,7 @@ static __inline void vm_pager_page_unswapped(vm_page_t m) { - VM_OBJECT_LOCK_ASSERT(m->object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(m->object, RA_WLOCKED); if (pagertab[m->object->type]->pgo_pageunswapped) (*pagertab[m->object->type]->pgo_pageunswapped)(m); } Index: vm/vm_init.c =================================================================== --- vm/vm_init.c (.../head/sys) (revision 247097) +++ vm/vm_init.c (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -68,8 +68,8 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include +#include #include #include #include Index: vm/vm_pageout.c =================================================================== --- vm/vm_pageout.c (.../head/sys) (revision 247097) +++ vm/vm_pageout.c (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -92,6 +92,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -248,7 +249,7 @@ vm_pageout_init_marker(vm_page_t marker, u_short q /* * vm_pageout_fallback_object_lock: * - * Lock vm object currently associated with `m'. VM_OBJECT_TRYLOCK is + * Lock vm object currently associated with `m'. VM_OBJECT_TRYWLOCK is * known to have failed and page queue must be either PQ_ACTIVE or * PQ_INACTIVE. To avoid lock order violation, unlock the page queues * while locking the vm object. Use marker page to detect page queue @@ -276,7 +277,7 @@ vm_pageout_fallback_object_lock(vm_page_t m, vm_pa TAILQ_INSERT_AFTER(&pq->pq_pl, m, &marker, pageq); vm_pagequeue_unlock(pq); vm_page_unlock(m); - VM_OBJECT_LOCK(object); + VM_OBJECT_WLOCK(object); vm_page_lock(m); vm_pagequeue_lock(pq); @@ -346,7 +347,7 @@ vm_pageout_clean(vm_page_t m) vm_page_lock_assert(m, MA_OWNED); object = m->object; - VM_OBJECT_LOCK_ASSERT(object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(object, RA_WLOCKED); /* * It doesn't cost us anything to pageout OBJT_DEFAULT or OBJT_SWAP @@ -484,7 +485,7 @@ vm_pageout_flush(vm_page_t *mc, int count, int fla int numpagedout = 0; int i, runlen; - VM_OBJECT_LOCK_ASSERT(object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(object, RA_WLOCKED); /* * Initiate I/O. Bump the vm_page_t->busy counter and @@ -595,12 +596,12 @@ vm_pageout_launder(int queue, int tries, vm_paddr_ continue; } object = m->object; - if ((!VM_OBJECT_TRYLOCK(object) && + if ((!VM_OBJECT_TRYWLOCK(object) && (!vm_pageout_fallback_object_lock(m, &next) || m->hold_count != 0)) || (m->oflags & VPO_BUSY) != 0 || m->busy != 0) { vm_page_unlock(m); - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); continue; } vm_page_test_dirty(m); @@ -609,19 +610,19 @@ vm_pageout_launder(int queue, int tries, vm_paddr_ if (m->dirty != 0) { vm_page_unlock(m); if (tries == 0 || (object->flags & OBJ_DEAD) != 0) { - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); continue; } if (object->type == OBJT_VNODE) { vm_pagequeue_unlock(pq); vp = object->handle; vm_object_reference_locked(object); - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); (void)vn_start_write(vp, &mp, V_WAIT); vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); - VM_OBJECT_LOCK(object); + VM_OBJECT_WLOCK(object); vm_object_page_clean(object, 0, 0, OBJPC_SYNC); - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); VOP_UNLOCK(vp, 0); vm_object_deallocate(object); vn_finished_write(mp); @@ -632,7 +633,7 @@ vm_pageout_launder(int queue, int tries, vm_paddr_ m_tmp = m; vm_pageout_flush(&m_tmp, 1, VM_PAGER_PUT_SYNC, 0, NULL, NULL); - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); return (TRUE); } } else { @@ -644,7 +645,7 @@ vm_pageout_launder(int queue, int tries, vm_paddr_ vm_page_cache(m); vm_page_unlock(m); } - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); } vm_pagequeue_unlock(pq); return (FALSE); @@ -713,13 +714,13 @@ vm_pageout_object_deactivate_pages(pmap_t pmap, vm vm_page_t p; int actcount, remove_mode; - VM_OBJECT_LOCK_ASSERT(first_object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(first_object, RA_WLOCKED); if ((first_object->flags & OBJ_FICTITIOUS) != 0) return; for (object = first_object;; object = backing_object) { if (pmap_resident_count(pmap) <= desired) goto unlock_return; - VM_OBJECT_LOCK_ASSERT(object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(object, RA_WLOCKED); if ((object->flags & OBJ_UNMANAGED) != 0 || object->paging_in_progress != 0) goto unlock_return; @@ -775,13 +776,13 @@ vm_pageout_object_deactivate_pages(pmap_t pmap, vm } if ((backing_object = object->backing_object) == NULL) goto unlock_return; - VM_OBJECT_LOCK(backing_object); + VM_OBJECT_WLOCK(backing_object); if (object != first_object) - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); } unlock_return: if (object != first_object) - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); } /* @@ -811,15 +812,15 @@ vm_pageout_map_deactivate_pages(map, desired) while (tmpe != &map->header) { if ((tmpe->eflags & MAP_ENTRY_IS_SUB_MAP) == 0) { obj = tmpe->object.vm_object; - if (obj != NULL && VM_OBJECT_TRYLOCK(obj)) { + if (obj != NULL && VM_OBJECT_TRYWLOCK(obj)) { if (obj->shadow_count <= 1 && (bigobj == NULL || bigobj->resident_page_count < obj->resident_page_count)) { if (bigobj != NULL) - VM_OBJECT_UNLOCK(bigobj); + VM_OBJECT_WUNLOCK(bigobj); bigobj = obj; } else - VM_OBJECT_UNLOCK(obj); + VM_OBJECT_WUNLOCK(obj); } } if (tmpe->wired_count > 0) @@ -829,7 +830,7 @@ vm_pageout_map_deactivate_pages(map, desired) if (bigobj != NULL) { vm_pageout_object_deactivate_pages(map->pmap, bigobj, desired); - VM_OBJECT_UNLOCK(bigobj); + VM_OBJECT_WUNLOCK(bigobj); } /* * Next, hunt around for other pages to deactivate. We actually @@ -842,9 +843,9 @@ vm_pageout_map_deactivate_pages(map, desired) if ((tmpe->eflags & MAP_ENTRY_IS_SUB_MAP) == 0) { obj = tmpe->object.vm_object; if (obj != NULL) { - VM_OBJECT_LOCK(obj); + VM_OBJECT_WLOCK(obj); vm_pageout_object_deactivate_pages(map->pmap, obj, desired); - VM_OBJECT_UNLOCK(obj); + VM_OBJECT_WUNLOCK(obj); } } tmpe = tmpe->next; @@ -963,10 +964,10 @@ vm_pageout_scan(int pass) continue; } object = m->object; - if (!VM_OBJECT_TRYLOCK(object) && + if (!VM_OBJECT_TRYWLOCK(object) && !vm_pageout_fallback_object_lock(m, &next)) { vm_page_unlock(m); - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); continue; } @@ -979,7 +980,7 @@ vm_pageout_scan(int pass) */ if (m->busy != 0 || (m->oflags & VPO_BUSY) != 0) { vm_page_unlock(m); - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); addl_page_shortage++; continue; } @@ -1016,7 +1017,7 @@ vm_pageout_scan(int pass) vm_page_activate(m); vm_page_unlock(m); m->act_count += actcount + ACT_ADVANCE; - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); goto relock_queues; } @@ -1032,13 +1033,13 @@ vm_pageout_scan(int pass) vm_page_activate(m); vm_page_unlock(m); m->act_count += actcount + ACT_ADVANCE + 1; - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); goto relock_queues; } if (m->hold_count != 0) { vm_page_unlock(m); - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); /* * Held pages are essentially stuck in the @@ -1122,7 +1123,7 @@ vm_pageout_scan(int pass) if (!swap_pageouts_ok || (object->flags & OBJ_DEAD)) { vm_pagequeue_lock(pq); vm_page_unlock(m); - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); queues_locked = TRUE; vm_page_requeue_locked(m); goto relock_queues; @@ -1165,17 +1166,17 @@ vm_pageout_scan(int pass) KASSERT(mp != NULL, ("vp %p with NULL v_mount", vp)); vm_object_reference_locked(object); - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); if (vget(vp, LK_EXCLUSIVE | LK_TIMELOCK, curthread)) { - VM_OBJECT_LOCK(object); + VM_OBJECT_WLOCK(object); ++pageout_lock_miss; if (object->flags & OBJ_MIGHTBEDIRTY) vnodes_skipped++; vp = NULL; goto unlock_and_continue; } - VM_OBJECT_LOCK(object); + VM_OBJECT_WLOCK(object); vm_page_lock(m); vm_pagequeue_lock(pq); queues_locked = TRUE; @@ -1236,7 +1237,7 @@ vm_pageout_scan(int pass) } unlock_and_continue: vm_page_lock_assert(m, MA_NOTOWNED); - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); if (mp != NULL) { if (queues_locked) { vm_pagequeue_unlock(pq); @@ -1251,7 +1252,7 @@ unlock_and_continue: goto relock_queues; } vm_page_unlock(m); - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); relock_queues: if (!queues_locked) { vm_pagequeue_lock(pq); @@ -1299,9 +1300,9 @@ relock_queues: continue; } object = m->object; - if (!VM_OBJECT_TRYLOCK(object) && + if (!VM_OBJECT_TRYWLOCK(object) && !vm_pageout_fallback_object_lock(m, &next)) { - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); vm_page_unlock(m); m = next; continue; @@ -1314,7 +1315,7 @@ relock_queues: (m->oflags & VPO_BUSY) || (m->hold_count != 0)) { vm_page_unlock(m); - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); vm_page_requeue_locked(m); m = next; continue; @@ -1375,7 +1376,7 @@ relock_queues: vm_page_requeue_locked(m); } vm_page_unlock(m); - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); m = next; } vm_pagequeue_unlock(pq); @@ -1571,9 +1572,9 @@ vm_pageout_page_stats(void) continue; } object = m->object; - if (!VM_OBJECT_TRYLOCK(object) && + if (!VM_OBJECT_TRYWLOCK(object) && !vm_pageout_fallback_object_lock(m, &next)) { - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); vm_page_unlock(m); m = next; continue; @@ -1586,7 +1587,7 @@ vm_pageout_page_stats(void) (m->oflags & VPO_BUSY) || (m->hold_count != 0)) { vm_page_unlock(m); - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); vm_page_requeue_locked(m); m = next; continue; @@ -1625,7 +1626,7 @@ vm_pageout_page_stats(void) } } vm_page_unlock(m); - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); m = next; } vm_pagequeue_unlock(pq); Index: vm/vm_object.c =================================================================== --- vm/vm_object.c (.../head/sys) (revision 247097) +++ vm/vm_object.c (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -78,6 +78,7 @@ __FBSDID("$FreeBSD$"); #include /* for curproc, pageproc */ #include #include +#include #include #include #include @@ -193,8 +194,8 @@ vm_object_zinit(void *mem, int size, int flags) vm_object_t object; object = (vm_object_t)mem; - bzero(&object->mtx, sizeof(object->mtx)); - VM_OBJECT_LOCK_INIT(object, "standard object"); + bzero(&object->lock, sizeof(object->lock)); + VM_OBJECT_LOCK_INIT(object, "standard vm object"); /* These are true for any object that has been freed */ object->paging_in_progress = 0; @@ -266,7 +267,7 @@ vm_object_init(void) TAILQ_INIT(&vm_object_list); mtx_init(&vm_object_list_mtx, "vm object_list", NULL, MTX_DEF); - VM_OBJECT_LOCK_INIT(kernel_object, "kernel object"); + VM_OBJECT_LOCK_INIT(kernel_object, "kernel vm object"); _vm_object_allocate(OBJT_PHYS, OFF_TO_IDX(VM_MAX_KERNEL_ADDRESS - VM_MIN_KERNEL_ADDRESS), kernel_object); #if VM_NRESERVLEVEL > 0 @@ -274,7 +275,7 @@ vm_object_init(void) kernel_object->pg_color = (u_short)atop(VM_MIN_KERNEL_ADDRESS); #endif - VM_OBJECT_LOCK_INIT(kmem_object, "kmem object"); + VM_OBJECT_LOCK_INIT(kmem_object, "kmem vm object"); _vm_object_allocate(OBJT_PHYS, OFF_TO_IDX(VM_MAX_KERNEL_ADDRESS - VM_MIN_KERNEL_ADDRESS), kmem_object); #if VM_NRESERVLEVEL > 0 @@ -300,7 +301,7 @@ void vm_object_clear_flag(vm_object_t object, u_short bits) { - VM_OBJECT_LOCK_ASSERT(object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(object, RA_WLOCKED); object->flags &= ~bits; } @@ -317,7 +318,7 @@ int vm_object_set_memattr(vm_object_t object, vm_memattr_t memattr) { - VM_OBJECT_LOCK_ASSERT(object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(object, RA_WLOCKED); switch (object->type) { case OBJT_DEFAULT: case OBJT_DEVICE: @@ -343,7 +344,7 @@ void vm_object_pip_add(vm_object_t object, short i) { - VM_OBJECT_LOCK_ASSERT(object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(object, RA_WLOCKED); object->paging_in_progress += i; } @@ -351,7 +352,7 @@ void vm_object_pip_subtract(vm_object_t object, short i) { - VM_OBJECT_LOCK_ASSERT(object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(object, RA_WLOCKED); object->paging_in_progress -= i; } @@ -359,7 +360,7 @@ void vm_object_pip_wakeup(vm_object_t object) { - VM_OBJECT_LOCK_ASSERT(object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(object, RA_WLOCKED); object->paging_in_progress--; if ((object->flags & OBJ_PIPWNT) && object->paging_in_progress == 0) { vm_object_clear_flag(object, OBJ_PIPWNT); @@ -371,7 +372,7 @@ void vm_object_pip_wakeupn(vm_object_t object, short i) { - VM_OBJECT_LOCK_ASSERT(object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(object, RA_WLOCKED); if (i) object->paging_in_progress -= i; if ((object->flags & OBJ_PIPWNT) && object->paging_in_progress == 0) { @@ -384,10 +385,10 @@ void vm_object_pip_wait(vm_object_t object, char *waitid) { - VM_OBJECT_LOCK_ASSERT(object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(object, RA_WLOCKED); while (object->paging_in_progress) { object->flags |= OBJ_PIPWNT; - msleep(object, VM_OBJECT_MTX(object), PVM, waitid, 0); + VM_OBJECT_SLEEP(object, object, PVM, waitid, 0); } } @@ -418,9 +419,9 @@ vm_object_reference(vm_object_t object) { if (object == NULL) return; - VM_OBJECT_LOCK(object); + VM_OBJECT_WLOCK(object); vm_object_reference_locked(object); - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); } /* @@ -435,7 +436,7 @@ vm_object_reference_locked(vm_object_t object) { struct vnode *vp; - VM_OBJECT_LOCK_ASSERT(object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(object, RA_WLOCKED); object->ref_count++; if (object->type == OBJT_VNODE) { vp = object->handle; @@ -451,7 +452,7 @@ vm_object_vndeallocate(vm_object_t object) { struct vnode *vp = (struct vnode *) object->handle; - VM_OBJECT_LOCK_ASSERT(object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(object, RA_WLOCKED); KASSERT(object->type == OBJT_VNODE, ("vm_object_vndeallocate: not a vnode object")); KASSERT(vp != NULL, ("vm_object_vndeallocate: missing vp")); @@ -464,23 +465,23 @@ vm_object_vndeallocate(vm_object_t object) if (object->ref_count > 1) { object->ref_count--; - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); /* vrele may need the vnode lock. */ vrele(vp); } else { vhold(vp); - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); vdrop(vp); - VM_OBJECT_LOCK(object); + VM_OBJECT_WLOCK(object); object->ref_count--; if (object->type == OBJT_DEAD) { - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); VOP_UNLOCK(vp, 0); } else { if (object->ref_count == 0) VOP_UNSET_TEXT(vp); - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); vput(vp); } } @@ -503,7 +504,7 @@ vm_object_deallocate(vm_object_t object) vm_object_t temp; while (object != NULL) { - VM_OBJECT_LOCK(object); + VM_OBJECT_WLOCK(object); if (object->type == OBJT_VNODE) { vm_object_vndeallocate(object); return; @@ -520,7 +521,7 @@ vm_object_deallocate(vm_object_t object) */ object->ref_count--; if (object->ref_count > 1) { - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); return; } else if (object->ref_count == 1) { if (object->shadow_count == 0 && @@ -539,12 +540,12 @@ vm_object_deallocate(vm_object_t object) ("vm_object_deallocate: ref_count: %d, shadow_count: %d", object->ref_count, object->shadow_count)); - if (!VM_OBJECT_TRYLOCK(robject)) { + if (!VM_OBJECT_TRYWLOCK(robject)) { /* * Avoid a potential deadlock. */ object->ref_count++; - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); /* * More likely than not the thread * holding robject's lock has lower @@ -568,28 +569,27 @@ vm_object_deallocate(vm_object_t object) robject->ref_count++; retry: if (robject->paging_in_progress) { - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); vm_object_pip_wait(robject, "objde1"); temp = robject->backing_object; if (object == temp) { - VM_OBJECT_LOCK(object); + VM_OBJECT_WLOCK(object); goto retry; } } else if (object->paging_in_progress) { - VM_OBJECT_UNLOCK(robject); + VM_OBJECT_WUNLOCK(robject); object->flags |= OBJ_PIPWNT; - msleep(object, - VM_OBJECT_MTX(object), - PDROP | PVM, "objde2", 0); - VM_OBJECT_LOCK(robject); + VM_OBJECT_SLEEP(object, object, + PDROP | PVM, "objde2" , 0); + VM_OBJECT_WLOCK(robject); temp = robject->backing_object; if (object == temp) { - VM_OBJECT_LOCK(object); + VM_OBJECT_WLOCK(object); goto retry; } } else - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); if (robject->ref_count == 1) { robject->ref_count--; @@ -598,21 +598,21 @@ retry: } object = robject; vm_object_collapse(object); - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); continue; } - VM_OBJECT_UNLOCK(robject); + VM_OBJECT_WUNLOCK(robject); } - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); return; } doterm: temp = object->backing_object; if (temp != NULL) { - VM_OBJECT_LOCK(temp); + VM_OBJECT_WLOCK(temp); LIST_REMOVE(object, shadow_list); temp->shadow_count--; - VM_OBJECT_UNLOCK(temp); + VM_OBJECT_WUNLOCK(temp); object->backing_object = NULL; } /* @@ -623,7 +623,7 @@ doterm: if ((object->flags & OBJ_DEAD) == 0) vm_object_terminate(object); else - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); object = temp; } } @@ -675,7 +675,7 @@ vm_object_terminate(vm_object_t object) { vm_page_t p, p_next; - VM_OBJECT_LOCK_ASSERT(object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(object, RA_WLOCKED); /* * Make sure no one uses us. @@ -701,11 +701,11 @@ vm_object_terminate(vm_object_t object) * Clean pages and flush buffers. */ vm_object_page_clean(object, 0, 0, OBJPC_SYNC); - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); vinvalbuf(vp, V_SAVE, 0, 0); - VM_OBJECT_LOCK(object); + VM_OBJECT_WLOCK(object); } KASSERT(object->ref_count == 0, @@ -760,7 +760,7 @@ vm_object_terminate(vm_object_t object) * Let the pager know object is dead. */ vm_pager_deallocate(object); - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); vm_object_destroy(object); } @@ -816,7 +816,7 @@ vm_object_page_clean(vm_object_t object, vm_ooffse int curgeneration, n, pagerflags; boolean_t clearobjflags, eio, res; - VM_OBJECT_LOCK_ASSERT(object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(object, RA_WLOCKED); KASSERT(object->type == OBJT_VNODE, ("Not a vnode object")); if ((object->flags & OBJ_MIGHTBEDIRTY) == 0 || object->resident_page_count == 0) @@ -902,7 +902,7 @@ vm_object_page_collect_flush(vm_object_t object, v int count, i, mreq, runlen; vm_page_lock_assert(p, MA_NOTOWNED); - VM_OBJECT_LOCK_ASSERT(object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(object, RA_WLOCKED); count = 1; mreq = 0; @@ -960,11 +960,11 @@ vm_object_sync(vm_object_t object, vm_ooffset_t of return (TRUE); res = TRUE; error = 0; - VM_OBJECT_LOCK(object); + VM_OBJECT_WLOCK(object); while ((backing_object = object->backing_object) != NULL) { - VM_OBJECT_LOCK(backing_object); + VM_OBJECT_WLOCK(backing_object); offset += object->backing_object_offset; - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); object = backing_object; if (object->size < OFF_TO_IDX(offset + size)) size = IDX_TO_OFF(object->size) - offset; @@ -984,7 +984,7 @@ vm_object_sync(vm_object_t object, vm_ooffset_t of if (object->type == OBJT_VNODE && (object->flags & OBJ_MIGHTBEDIRTY) != 0) { vp = object->handle; - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); (void) vn_start_write(vp, &mp, V_WAIT); vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); if (syncio && !invalidate && offset == 0 && @@ -1002,17 +1002,17 @@ vm_object_sync(vm_object_t object, vm_ooffset_t of flags |= invalidate ? (OBJPC_SYNC | OBJPC_INVAL) : 0; fsync_after = FALSE; } - VM_OBJECT_LOCK(object); + VM_OBJECT_WLOCK(object); res = vm_object_page_clean(object, offset, offset + size, flags); - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); if (fsync_after) error = VOP_FSYNC(vp, MNT_WAIT, curthread); VOP_UNLOCK(vp, 0); vn_finished_write(mp); if (error != 0) res = FALSE; - VM_OBJECT_LOCK(object); + VM_OBJECT_WLOCK(object); } if ((object->type == OBJT_VNODE || object->type == OBJT_DEVICE) && invalidate) { @@ -1030,7 +1030,7 @@ vm_object_sync(vm_object_t object, vm_ooffset_t of vm_object_page_remove(object, OFF_TO_IDX(offset), OFF_TO_IDX(offset + size + PAGE_MASK), flags); } - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); return (res); } @@ -1065,7 +1065,7 @@ vm_object_madvise(vm_object_t object, vm_pindex_t if (object == NULL) return; - VM_OBJECT_LOCK(object); + VM_OBJECT_WLOCK(object); /* * Locate and adjust resident pages */ @@ -1106,10 +1106,10 @@ shadowlookup: backing_object = tobject->backing_object; if (backing_object == NULL) goto unlock_tobject; - VM_OBJECT_LOCK(backing_object); + VM_OBJECT_WLOCK(backing_object); tpindex += OFF_TO_IDX(tobject->backing_object_offset); if (tobject != object) - VM_OBJECT_UNLOCK(tobject); + VM_OBJECT_WUNLOCK(tobject); tobject = backing_object; goto shadowlookup; } else if (m->valid != VM_PAGE_BITS_ALL) @@ -1137,11 +1137,10 @@ shadowlookup: } vm_page_unlock(m); if (object != tobject) - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); m->oflags |= VPO_WANTED; - msleep(m, VM_OBJECT_MTX(tobject), PDROP | PVM, "madvpo", - 0); - VM_OBJECT_LOCK(object); + VM_OBJECT_SLEEP(m, tobject, PDROP | PVM, "madvpo" , 0); + VM_OBJECT_WLOCK(object); goto relookup; } if (advise == MADV_WILLNEED) { @@ -1174,9 +1173,9 @@ shadowlookup: swap_pager_freespace(tobject, tpindex, 1); unlock_tobject: if (tobject != object) - VM_OBJECT_UNLOCK(tobject); + VM_OBJECT_WUNLOCK(tobject); } - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); } /* @@ -1204,15 +1203,15 @@ vm_object_shadow( * Don't create the new object if the old object isn't shared. */ if (source != NULL) { - VM_OBJECT_LOCK(source); + VM_OBJECT_WLOCK(source); if (source->ref_count == 1 && source->handle == NULL && (source->type == OBJT_DEFAULT || source->type == OBJT_SWAP)) { - VM_OBJECT_UNLOCK(source); + VM_OBJECT_WUNLOCK(source); return; } - VM_OBJECT_UNLOCK(source); + VM_OBJECT_WUNLOCK(source); } /* @@ -1237,7 +1236,7 @@ vm_object_shadow( */ result->backing_object_offset = *offset; if (source != NULL) { - VM_OBJECT_LOCK(source); + VM_OBJECT_WLOCK(source); LIST_INSERT_HEAD(&source->shadow_head, result, shadow_list); source->shadow_count++; #if VM_NRESERVLEVEL > 0 @@ -1245,7 +1244,7 @@ vm_object_shadow( result->pg_color = (source->pg_color + OFF_TO_IDX(*offset)) & ((1 << (VM_NFREEORDER - 1)) - 1); #endif - VM_OBJECT_UNLOCK(source); + VM_OBJECT_WUNLOCK(source); } @@ -1276,7 +1275,7 @@ vm_object_split(vm_map_entry_t entry) return; if (orig_object->ref_count <= 1) return; - VM_OBJECT_UNLOCK(orig_object); + VM_OBJECT_WUNLOCK(orig_object); offidxstart = OFF_TO_IDX(entry->offset); size = atop(entry->end - entry->start); @@ -1291,17 +1290,17 @@ vm_object_split(vm_map_entry_t entry) * At this point, the new object is still private, so the order in * which the original and new objects are locked does not matter. */ - VM_OBJECT_LOCK(new_object); - VM_OBJECT_LOCK(orig_object); + VM_OBJECT_WLOCK(new_object); + VM_OBJECT_WLOCK(orig_object); source = orig_object->backing_object; if (source != NULL) { - VM_OBJECT_LOCK(source); + VM_OBJECT_WLOCK(source); if ((source->flags & OBJ_DEAD) != 0) { - VM_OBJECT_UNLOCK(source); - VM_OBJECT_UNLOCK(orig_object); - VM_OBJECT_UNLOCK(new_object); + VM_OBJECT_WUNLOCK(source); + VM_OBJECT_WUNLOCK(orig_object); + VM_OBJECT_WUNLOCK(new_object); vm_object_deallocate(new_object); - VM_OBJECT_LOCK(orig_object); + VM_OBJECT_WLOCK(orig_object); return; } LIST_INSERT_HEAD(&source->shadow_head, @@ -1309,7 +1308,7 @@ vm_object_split(vm_map_entry_t entry) source->shadow_count++; vm_object_reference_locked(source); /* for new_object */ vm_object_clear_flag(source, OBJ_ONEMAPPING); - VM_OBJECT_UNLOCK(source); + VM_OBJECT_WUNLOCK(source); new_object->backing_object_offset = orig_object->backing_object_offset + entry->offset; new_object->backing_object = source; @@ -1336,10 +1335,10 @@ retry: * not be changed by this operation. */ if ((m->oflags & VPO_BUSY) || m->busy) { - VM_OBJECT_UNLOCK(new_object); + VM_OBJECT_WUNLOCK(new_object); m->oflags |= VPO_WANTED; - msleep(m, VM_OBJECT_MTX(orig_object), PVM, "spltwt", 0); - VM_OBJECT_LOCK(new_object); + VM_OBJECT_SLEEP(m, orig_object, PVM, "spltwt" , 0); + VM_OBJECT_WLOCK(new_object); goto retry; } #if VM_NRESERVLEVEL > 0 @@ -1383,14 +1382,14 @@ retry: vm_page_cache_transfer(orig_object, offidxstart, new_object); } - VM_OBJECT_UNLOCK(orig_object); + VM_OBJECT_WUNLOCK(orig_object); TAILQ_FOREACH(m, &new_object->memq, listq) vm_page_wakeup(m); - VM_OBJECT_UNLOCK(new_object); + VM_OBJECT_WUNLOCK(new_object); entry->object.vm_object = new_object; entry->offset = 0LL; vm_object_deallocate(orig_object); - VM_OBJECT_LOCK(new_object); + VM_OBJECT_WLOCK(new_object); } #define OBSC_TEST_ALL_SHADOWED 0x0001 @@ -1405,8 +1404,8 @@ vm_object_backing_scan(vm_object_t object, int op) vm_object_t backing_object; vm_pindex_t backing_offset_index; - VM_OBJECT_LOCK_ASSERT(object, MA_OWNED); - VM_OBJECT_LOCK_ASSERT(object->backing_object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(object, RA_WLOCKED); + VM_OBJECT_LOCK_ASSERT(object->backing_object, RA_WLOCKED); backing_object = object->backing_object; backing_offset_index = OFF_TO_IDX(object->backing_object_offset); @@ -1494,12 +1493,12 @@ vm_object_backing_scan(vm_object_t object, int op) } } else if (op & OBSC_COLLAPSE_WAIT) { if ((p->oflags & VPO_BUSY) || p->busy) { - VM_OBJECT_UNLOCK(object); + VM_OBJECT_WUNLOCK(object); p->oflags |= VPO_WANTED; - msleep(p, VM_OBJECT_MTX(backing_object), + VM_OBJECT_SLEEP(p, backing_object, PDROP | PVM, "vmocol", 0); - VM_OBJECT_LOCK(object); - VM_OBJECT_LOCK(backing_object); + VM_OBJECT_WLOCK(object); + VM_OBJECT_WLOCK(backing_object); /* * If we slept, anything could have * happened. Since the object is @@ -1626,8 +1625,8 @@ vm_object_qcollapse(vm_object_t object) { vm_object_t backing_object = object->backing_object; - VM_OBJECT_LOCK_ASSERT(object, MA_OWNED); - VM_OBJECT_LOCK_ASSERT(backing_object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(object, RA_WLOCKED); + VM_OBJECT_LOCK_ASSERT(backing_object, RA_WLOCKED); if (backing_object->ref_count != 1) return; @@ -1645,7 +1644,7 @@ vm_object_qcollapse(vm_object_t object) void vm_object_collapse(vm_object_t object) { - VM_OBJECT_LOCK_ASSERT(object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(object, RA_WLOCKED); while (TRUE) { vm_object_t backing_object; @@ -1662,7 +1661,7 @@ vm_object_collapse(vm_object_t object) * we check the backing object first, because it is most likely * not collapsable. */ - VM_OBJECT_LOCK(backing_object); + VM_OBJECT_WLOCK(backing_object); if (backing_object->handle != NULL || (backing_object->type != OBJT_DEFAULT && backing_object->type != OBJT_SWAP) || @@ -1671,7 +1670,7 @@ vm_object_collapse(vm_object_t object) (object->type != OBJT_DEFAULT && object->type != OBJT_SWAP) || (object->flags & OBJ_DEAD)) { - VM_OBJECT_UNLOCK(backing_object); + VM_OBJECT_WUNLOCK(backing_object); break; } @@ -1680,7 +1679,7 @@ vm_object_collapse(vm_object_t object) backing_object->paging_in_progress != 0 ) { vm_object_qcollapse(object); - VM_OBJECT_UNLOCK(backing_object); + VM_OBJECT_WUNLOCK(backing_object); break; } /* @@ -1740,7 +1739,7 @@ vm_object_collapse(vm_object_t object) LIST_REMOVE(object, shadow_list); backing_object->shadow_count--; if (backing_object->backing_object) { - VM_OBJECT_LOCK(backing_object->backing_object); + VM_OBJECT_WLOCK(backing_object->backing_object); LIST_REMOVE(backing_object, shadow_list); LIST_INSERT_HEAD( &backing_object->backing_object->shadow_head, @@ -1748,7 +1747,7 @@ vm_object_collapse(vm_object_t object) /* * The shadow_count has not changed. */ - VM_OBJECT_UNLOCK(backing_object->backing_object); + VM_OBJECT_WUNLOCK(backing_object->backing_object); } object->backing_object = backing_object->backing_object; object->backing_object_offset += @@ -1764,7 +1763,7 @@ vm_object_collapse(vm_object_t object) KASSERT(backing_object->ref_count == 1, ( "backing_object %p was somehow re-referenced during collapse!", backing_object)); - VM_OBJECT_UNLOCK(backing_object); + VM_OBJECT_WUNLOCK(backing_object); vm_object_destroy(backing_object); object_collapses++; @@ -1778,7 +1777,7 @@ vm_object_collapse(vm_object_t object) if (object->resident_page_count != object->size && vm_object_backing_scan(object, OBSC_TEST_ALL_SHADOWED) == 0) { - VM_OBJECT_UNLOCK(backing_object); + VM_OBJECT_WUNLOCK(backing_object); break; } @@ -1792,7 +1791,7 @@ vm_object_collapse(vm_object_t object) new_backing_object = backing_object->backing_object; if ((object->backing_object = new_backing_object) != NULL) { - VM_OBJECT_LOCK(new_backing_object); + VM_OBJECT_WLOCK(new_backing_object); LIST_INSERT_HEAD( &new_backing_object->shadow_head, object, @@ -1800,7 +1799,7 @@ vm_object_collapse(vm_object_t object) ); new_backing_object->shadow_count++; vm_object_reference_locked(new_backing_object); - VM_OBJECT_UNLOCK(new_backing_object); + VM_OBJECT_WUNLOCK(new_backing_object); object->backing_object_offset += backing_object->backing_object_offset; } @@ -1810,7 +1809,7 @@ vm_object_collapse(vm_object_t object) * its ref_count was at least 2, it will not vanish. */ backing_object->ref_count--; - VM_OBJECT_UNLOCK(backing_object); + VM_OBJECT_WUNLOCK(backing_object); object_bypasses++; } @@ -1853,7 +1852,7 @@ vm_object_page_remove(vm_object_t object, vm_pinde vm_page_t p, next; int wirings; - VM_OBJECT_LOCK_ASSERT(object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(object, RA_WLOCKED); KASSERT((object->flags & OBJ_UNMANAGED) == 0 || (options & (OBJPR_CLEANONLY | OBJPR_NOTMAPPED)) == OBJPR_NOTMAPPED, ("vm_object_page_remove: illegal options for object %p", object)); @@ -1948,7 +1947,7 @@ vm_object_page_cache(vm_object_t object, vm_pindex struct mtx *mtx, *new_mtx; vm_page_t p, next; - VM_OBJECT_LOCK_ASSERT(object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(object, RA_WLOCKED); KASSERT((object->flags & (OBJ_FICTITIOUS | OBJ_UNMANAGED)) == 0, ("vm_object_page_cache: illegal object %p", object)); if (object->resident_page_count == 0) @@ -1996,7 +1995,7 @@ vm_object_populate(vm_object_t object, vm_pindex_t vm_pindex_t pindex; int rv; - VM_OBJECT_LOCK_ASSERT(object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(object, RA_WLOCKED); for (pindex = start; pindex < end; pindex++) { m = vm_page_grab(object, pindex, VM_ALLOC_NORMAL | VM_ALLOC_RETRY); @@ -2057,10 +2056,10 @@ vm_object_coalesce(vm_object_t prev_object, vm_oof if (prev_object == NULL) return (TRUE); - VM_OBJECT_LOCK(prev_object); + VM_OBJECT_WLOCK(prev_object); if (prev_object->type != OBJT_DEFAULT && prev_object->type != OBJT_SWAP) { - VM_OBJECT_UNLOCK(prev_object); + VM_OBJECT_WUNLOCK(prev_object); return (FALSE); } @@ -2075,7 +2074,7 @@ vm_object_coalesce(vm_object_t prev_object, vm_oof * pages not mapped to prev_entry may be in use anyway) */ if (prev_object->backing_object != NULL) { - VM_OBJECT_UNLOCK(prev_object); + VM_OBJECT_WUNLOCK(prev_object); return (FALSE); } @@ -2085,7 +2084,7 @@ vm_object_coalesce(vm_object_t prev_object, vm_oof if ((prev_object->ref_count > 1) && (prev_object->size != next_pindex)) { - VM_OBJECT_UNLOCK(prev_object); + VM_OBJECT_WUNLOCK(prev_object); return (FALSE); } @@ -2139,7 +2138,7 @@ vm_object_coalesce(vm_object_t prev_object, vm_oof if (next_pindex + next_size > prev_object->size) prev_object->size = next_pindex + next_size; - VM_OBJECT_UNLOCK(prev_object); + VM_OBJECT_WUNLOCK(prev_object); return (TRUE); } @@ -2147,7 +2146,7 @@ void vm_object_set_writeable_dirty(vm_object_t object) { - VM_OBJECT_LOCK_ASSERT(object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(object, RA_WLOCKED); if (object->type != OBJT_VNODE) return; object->generation++; Index: vm/vm_reserv.c =================================================================== --- vm/vm_reserv.c (.../head/sys) (revision 247097) +++ vm/vm_reserv.c (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -47,6 +47,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -311,7 +312,7 @@ vm_reserv_alloc_contig(vm_object_t object, vm_pind int i, index, n; mtx_assert(&vm_page_queue_free_mtx, MA_OWNED); - VM_OBJECT_LOCK_ASSERT(object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(object, RA_WLOCKED); KASSERT(npages != 0, ("vm_reserv_alloc_contig: npages is 0")); /* @@ -495,7 +496,7 @@ vm_reserv_alloc_page(vm_object_t object, vm_pindex vm_reserv_t rv; mtx_assert(&vm_page_queue_free_mtx, MA_OWNED); - VM_OBJECT_LOCK_ASSERT(object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(object, RA_WLOCKED); /* * Is a reservation fundamentally impossible? @@ -870,7 +871,7 @@ vm_reserv_rename(vm_page_t m, vm_object_t new_obje { vm_reserv_t rv; - VM_OBJECT_LOCK_ASSERT(new_object, MA_OWNED); + VM_OBJECT_LOCK_ASSERT(new_object, RA_WLOCKED); rv = vm_reserv_from_page(m); if (rv->object == old_object) { mtx_lock(&vm_page_queue_free_mtx); Index: compat/linprocfs/linprocfs.c =================================================================== --- compat/linprocfs/linprocfs.c (.../head/sys) (revision 247097) +++ compat/linprocfs/linprocfs.c (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -1033,9 +1033,9 @@ linprocfs_doprocmaps(PFS_FILL_ARGS) e_end = entry->end; obj = entry->object.vm_object; for (lobj = tobj = obj; tobj; tobj = tobj->backing_object) { - VM_OBJECT_LOCK(tobj); + VM_OBJECT_WLOCK(tobj); if (lobj != obj) - VM_OBJECT_UNLOCK(lobj); + VM_OBJECT_WUNLOCK(lobj); lobj = tobj; } last_timestamp = map->timestamp; @@ -1051,11 +1051,11 @@ linprocfs_doprocmaps(PFS_FILL_ARGS) else vp = NULL; if (lobj != obj) - VM_OBJECT_UNLOCK(lobj); + VM_OBJECT_WUNLOCK(lobj); flags = obj->flags; ref_count = obj->ref_count; shadow_count = obj->shadow_count; - VM_OBJECT_UNLOCK(obj); + VM_OBJECT_WUNLOCK(obj); if (vp) { vn_fullpath(td, vp, &name, &freename); vn_lock(vp, LK_SHARED | LK_RETRY); Index: pc98/pc98/machdep.c =================================================================== --- pc98/pc98/machdep.c (.../head/sys) (revision 247097) +++ pc98/pc98/machdep.c (.../user/attilio/vmobj-rwlock/sys) (revision 247097) @@ -80,6 +80,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #ifdef SMP Index: . =================================================================== --- . (.../head/sys) (revision 247097) +++ . (.../user/attilio/vmobj-rwlock/sys) (revision 247097) Property changes on: . ___________________________________________________________________ Modified: svn:mergeinfo Merged /head/sys:r247016-247096