svn commit: r254138 - in head: share/man/man9 sys/amd64/amd64 sys/arm/arm sys/cddl/contrib/opensolaris/uts/common/fs/zfs sys/dev/agp sys/dev/drm2/i915 sys/dev/drm2/ttm sys/dev/md sys/fs/fuse sys/fs...

Attilio Rao attilio at FreeBSD.org
Fri Aug 9 11:11:16 UTC 2013


Author: attilio
Date: Fri Aug  9 11:11:11 2013
New Revision: 254138
URL: http://svnweb.freebsd.org/changeset/base/254138

Log:
  The soft and hard busy mechanism rely on the vm object lock to work.
  Unify the 2 concept into a real, minimal, sxlock where the shared
  acquisition represent the soft busy and the exclusive acquisition
  represent the hard busy.
  The old VPO_WANTED mechanism becames the hard-path for this new lock
  and it becomes per-page rather than per-object.
  The vm_object lock becames an interlock for this functionality:
  it can be held in both read or write mode.
  However, if the vm_object lock is held in read mode while acquiring
  or releasing the busy state, the thread owner cannot make any
  assumption on the busy state unless it is also busying it.
  
  Also:
  - Add a new flag to directly shared busy pages while vm_page_alloc
    and vm_page_grab are being executed.  This will be very helpful
    once these functions happen under a read object lock.
  - Move the swapping sleep into its own per-object flag
  
  The KPI is heavilly changed this is why the version is bumped.
  It is very likely that some VM ports users will need to change
  their own code.
  
  Sponsored by:	EMC / Isilon storage division
  Discussed with:	alc
  Reviewed by:	jeff, kib
  Tested by:	gavin, bapt (older version)
  Tested by:	pho, scottl

Added:
  head/share/man/man9/vm_page_busy.9   (contents, props changed)
Deleted:
  head/share/man/man9/vm_page_io.9
  head/share/man/man9/vm_page_sleep_if_busy.9
  head/share/man/man9/vm_page_wakeup.9
Modified:
  head/share/man/man9/Makefile
  head/share/man/man9/VOP_GETPAGES.9
  head/share/man/man9/vm_page_alloc.9
  head/sys/amd64/amd64/pmap.c
  head/sys/arm/arm/pmap-v6.c
  head/sys/arm/arm/pmap.c
  head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c
  head/sys/dev/agp/agp.c
  head/sys/dev/drm2/i915/i915_gem.c
  head/sys/dev/drm2/ttm/ttm_bo_vm.c
  head/sys/dev/drm2/ttm/ttm_tt.c
  head/sys/dev/md/md.c
  head/sys/fs/fuse/fuse_vnops.c
  head/sys/fs/tmpfs/tmpfs_subr.c
  head/sys/fs/tmpfs/tmpfs_vnops.c
  head/sys/i386/i386/pmap.c
  head/sys/i386/xen/pmap.c
  head/sys/ia64/ia64/pmap.c
  head/sys/kern/kern_exec.c
  head/sys/kern/subr_uio.c
  head/sys/kern/uipc_shm.c
  head/sys/kern/uipc_syscalls.c
  head/sys/kern/vfs_bio.c
  head/sys/kern/vfs_cluster.c
  head/sys/mips/mips/pmap.c
  head/sys/powerpc/aim/mmu_oea.c
  head/sys/powerpc/aim/mmu_oea64.c
  head/sys/powerpc/booke/pmap.c
  head/sys/sparc64/sparc64/pmap.c
  head/sys/sys/param.h
  head/sys/vm/phys_pager.c
  head/sys/vm/swap_pager.c
  head/sys/vm/vm_fault.c
  head/sys/vm/vm_glue.c
  head/sys/vm/vm_object.c
  head/sys/vm/vm_page.c
  head/sys/vm/vm_page.h
  head/sys/vm/vm_pageout.c
  head/sys/vm/vm_phys.c
  head/sys/vm/vnode_pager.c

Modified: head/share/man/man9/Makefile
==============================================================================
--- head/share/man/man9/Makefile	Fri Aug  9 09:48:05 2013	(r254137)
+++ head/share/man/man9/Makefile	Fri Aug  9 11:11:11 2013	(r254138)
@@ -332,11 +332,8 @@ MAN=	accept_filter.9 \
 	vm_page_grab.9 \
 	vm_page_hold.9 \
 	vm_page_insert.9 \
-	vm_page_io.9 \
 	vm_page_lookup.9 \
 	vm_page_rename.9 \
-	vm_page_sleep_if_busy.9 \
-	vm_page_wakeup.9 \
 	vm_page_wire.9 \
 	vm_set_page_size.9 \
 	vmem.9 \
@@ -1465,6 +1462,21 @@ MLINKS+=vm_page_bits.9 vm_page_clear_dir
 	vm_page_bits.9 vm_page_test_dirty.9 \
 	vm_page_bits.9 vm_page_undirty.9 \
 	vm_page_bits.9 vm_page_zero_invalid.9
+MLINKS+=vm_page_busy.9 vm_page_busied.9 \
+	vm_page_busy.9 vm_page_busy_downgrade.9 \
+	vm_page_busy.9 vm_page_busy_sleep.9 \
+	vm_page_busy.9 vm_page_sbusied.9 \
+	vm_page_busy.9 vm_page_sbusy.9 \
+	vm_page_busy.9 vm_page_sleep_if_busy.9 \
+	vm_page_busy.9 vm_page_sunbusy.9 \
+	vm_page_busy.9 vm_page_trysbusy.9 \
+	vm_page_busy.9 vm_page_tryxbusy.9 \
+	vm_page_busy.9 vm_page_xbusied.9 \
+	vm_page_busy.9 vm_page_xbusy.9 \
+	vm_page_busy.9 vm_page_xunbusy.9 \
+	vm_page_busy.9 vm_page_assert_sbusied.9 \
+	vm_page_busy.9 vm_page_assert_unbusied.9 \
+	vm_page_busy.9 vm_page_assert_xbusied.9
 MLINKS+=vm_page_aflag.9 vm_page_aflag_clear.9 \
 	vm_page_aflag.9 vm_page_aflag_set.9 \
 	vm_page_aflag.9 vm_page_reference.9
@@ -1473,10 +1485,6 @@ MLINKS+=vm_page_free.9 vm_page_free_toq.
 	vm_page_free.9 vm_page_try_to_free.9
 MLINKS+=vm_page_hold.9 vm_page_unhold.9
 MLINKS+=vm_page_insert.9 vm_page_remove.9
-MLINKS+=vm_page_io.9 vm_page_io_finish.9 \
-	vm_page_io.9 vm_page_io_start.9
-MLINKS+=vm_page_wakeup.9 vm_page_busy.9 \
-	vm_page_wakeup.9 vm_page_flash.9
 MLINKS+=vm_page_wire.9 vm_page_unwire.9
 MLINKS+=VOP_ACCESS.9 VOP_ACCESSX.9
 MLINKS+=VOP_ATTRIB.9 VOP_GETATTR.9 \

Modified: head/share/man/man9/VOP_GETPAGES.9
==============================================================================
--- head/share/man/man9/VOP_GETPAGES.9	Fri Aug  9 09:48:05 2013	(r254137)
+++ head/share/man/man9/VOP_GETPAGES.9	Fri Aug  9 11:11:11 2013	(r254138)
@@ -102,7 +102,7 @@ When the write completes, the completion
 call
 .Xr vm_object_pip_wakeup 9
 and
-.Xr vm_page_io_finish 9
+.Xr vm_page_sunbusy 9
 to clear the busy flag and awaken any other threads waiting for this page,
 in addition to calling
 .Xr vm_page_undirty 9 .
@@ -139,7 +139,7 @@ For example,
 .Fn VOP_GETPAGES
 may either activate a page (if its wanted bit is set)
 or deactivate it (otherwise), and finally call
-.Xr vm_page_wakeup 9
+.Xr vm_page_xunbusy 9
 to arouse any threads currently waiting for the page to be faulted in.
 .Sh RETURN VALUES
 If it successfully reads
@@ -156,9 +156,9 @@ is
 .Sh SEE ALSO
 .Xr vm_object_pip_wakeup 9 ,
 .Xr vm_page_free 9 ,
-.Xr vm_page_io_finish 9 ,
+.Xr vm_pagge_sunbusy 9 ,
 .Xr vm_page_undirty 9 ,
-.Xr vm_page_wakeup 9 ,
+.Xr vm_page_xunbusy 9 ,
 .Xr vnode 9
 .Sh AUTHORS
 This manual page was written by

Modified: head/share/man/man9/vm_page_alloc.9
==============================================================================
--- head/share/man/man9/vm_page_alloc.9	Fri Aug  9 09:48:05 2013	(r254137)
+++ head/share/man/man9/vm_page_alloc.9	Fri Aug  9 11:11:11 2013	(r254138)
@@ -91,9 +91,7 @@ than zero.
 The optional flags are:
 .Bl -tag -width ".Dv VM_ALLOC_IFNOTCACHED"
 .It Dv VM_ALLOC_NOBUSY
-The returned page will not have the
-.Dv VPO_BUSY
-flag set.
+The returned page will not be exclusive busy.
 .It Dv VM_ALLOC_NODUMP
 The returned page will not be included in any kernel core dumps
 regardless of whether or not it is mapped in to KVA.
@@ -112,6 +110,8 @@ Only allocate the page if it is not cach
 If the page at the specified
 .Fa pindex
 is cached, NULL is returned instead.
+.It Dv VM_ALLOC_SBUSY
+The returned page will be shared busy.
 .It Dv VM_ALLOC_WIRED
 The returned page will be wired.
 .It Dv VM_ALLOC_ZERO

Added: head/share/man/man9/vm_page_busy.9
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/share/man/man9/vm_page_busy.9	Fri Aug  9 11:11:11 2013	(r254138)
@@ -0,0 +1,216 @@
+.\"
+.\" 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 AUTHOR 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 AUTHOR 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$
+.Dd August 07, 2013
+.Dt vm_page_busy 9
+.Os
+.Sh NAME
+.Nm vm_page_busied ,
+.Nm vm_page_busy_downgrade ,
+.Nm vm_page_busy_sleep ,
+.Nm vm_page_sbusied ,
+.Nm vm_page_sbusy ,
+.Nm vm_page_sleep_if_busy ,
+.Nm vm_page_sunbusy ,
+.Nm vm_page_trysbusy ,
+.Nm vm_page_tryxbusy ,
+.Nm vm_page_xbusied ,
+.Nm vm_page_xbusy ,
+.Nm vm_page_xunbusy ,
+.Nm vm_page_assert_sbusied ,
+.Nm vm_page_assert_unbusied ,
+.Nm vm_page_assert_xbusied
+.Nd protect page identity changes and page content references
+.Sh SYNOPSIS
+.In sys/param.h
+.In vm/vm.h
+.In vm/vm_page.h
+.Ft int
+.Fn vm_page_busied "vm_page_t m"
+.Ft void
+.Fn vm_page_busy_downgrade "vm_page_t m"
+.Ft void
+.Fn vm_page_busy_sleep "vm_page_t m" "const char *msg"
+.Ft int
+.Fn vm_page_sbusied "vm_page_t m"
+.Ft void
+.Fn vm_page_sbusy "vm_page_t m"
+.Ft int
+.Fn vm_page_sleep_if_busy "vm_page_t m" "const char *msg"
+.Ft void
+.Fn vm_page_sunbusy "vm_page_t m"
+.Ft int
+.Fn vm_page_trysbusy "vm_page_t m"
+.Ft int
+.Fn vm_page_tryxbusy "vm_page_t m"
+.Ft int
+.Fn vm_page_xbusied "vm_page_t m"
+.Ft void
+.Fn vm_page_xbusy "vm_page_t m"
+.Ft void
+.Fn vm_page_xunbusy "vm_page_t m"
+.Pp
+.Cd "options INVARIANTS"
+.Cd "options INVARIANT_SUPPORT"
+.Ft void
+.Fn vm_page_assert_sbusied "vm_page_t m"
+.Ft void
+.Fn vm_page_assert_unbusied "vm_page_t m"
+.Ft void
+.Fn vm_page_assert_xbusied "vm_page_t m"
+.Sh DESCRIPTION
+Page identity is usually protected by higher level locks like vm_object
+locks and vm page locks.
+However, sometimes it is not possible to hold such locks for the time
+necessary to complete the identity change.
+In such case the page can be exclusively busied by a thread which needs
+to own the identity for a certain amount of time.
+.Pp
+In other situations, threads do not need to change the identity of the
+page but they want to prevent other threads from changing the identity
+themselves.
+For example, when a thread wants to access or update page contents
+without a lock held the page is shared busied.
+.Pp
+Before busing a page the vm_object lock must be held.
+The same rule applies when a page is unbusied.
+This makes the vm_object lock a real busy interlock.
+.Pp
+The
+.Fn vm_page_busied
+function returns non-zero if the current thread busied
+.Fa m
+in either exclusive or shared mode.
+Returns zero otherwise.
+.Pp
+The
+.Fn vm_page_busy_downgrade
+function must be used to downgrade
+.Fa m
+from an exclusive busy state to a shared busy state.
+.Pp
+The
+.Fn vm_page_busy_sleep
+function puts the invoking thread to sleep using the appropriate
+waitchannels for the busy mechanism.
+The parameter
+.Fa msg
+is a string describing the sleep condition for userland tools.
+.Pp
+The
+.Fn vm_page_busied
+function returns non-zero if the current thread busied
+.Fa m
+in shared mode.
+Returns zero otherwise.
+.Pp
+The
+.Fn vm_page_sbusy
+function shared busies
+.Fa m .
+.Pp
+The
+.Fn vm_page_sleep_if_busy
+function puts the invoking thread to sleep, using the appropriate
+waitchannels for the busy mechanism, if
+.Fa m .
+is busied in either exclusive or shared mode.
+If the invoking thread slept a non-zero value is returned, otherwise
+0 is returned.
+The parameter
+.Fa msg
+is a string describing the sleep condition for userland tools.
+.Pp
+The
+.Fn vm_page_sunbusy
+function shared unbusies
+.Fa m .
+.Pp
+The
+.Fn vm_page_trysbusy
+attempts to shared busy
+.Fa m .
+If the operation cannot immediately succeed
+.Fn vm_page_trysbusy
+returns 0, otherwise a non-zero value is returned.
+.Pp
+The
+.Fn vm_page_tryxbusy
+attempts to exclusive busy
+.Fa m .
+If the operation cannot immediately succeed
+.Fn vm_page_tryxbusy
+returns 0, otherwise a non-zero value is returned.
+.Pp
+The
+.Fn vm_page_xbusied
+function returns non-zero if the current thread busied
+.Fa m
+in exclusive mode.
+Returns zero otherwise.
+.Pp
+The
+.Fn vm_page_xbusy
+function exclusive busies
+.Fa m .
+.Pp
+The
+.Fn vm_page_xunbusy
+function exclusive unbusies
+.Fa m .
+Assertions on the busy state allow kernels compiled with
+.Cd "options INVARIANTS"
+and
+.Cd "options INVARIANT_SUPPORT"
+to panic if they are not respected.
+.Pp
+The
+.Fn vm_page_assert_sbusied
+function panics if
+.Fa m
+is not shared busied.
+.Pp
+The
+.Fn vm_page_assert_unbusied
+function panics if
+.Fa m
+is not unbusied.
+.Pp
+The
+.Fn vm_page_assert_xbusied
+function panics if
+.Fa m
+is not exclusive busied.
+.Sh SEE ALSO
+.Xr VOP_GETPAGES 9 ,
+.Xr vm_page_aflag 9 ,
+.Xr vm_page_alloc 9 ,
+.Xr vm_page_deactivate 9 ,
+.Xr vm_page_free 9 ,
+.Xr vm_page_grab 9 ,
+.Xr vm_page_insert 9 ,
+.Xr vm_page_lookup 9 ,
+.Xr vm_page_rename 9

Modified: head/sys/amd64/amd64/pmap.c
==============================================================================
--- head/sys/amd64/amd64/pmap.c	Fri Aug  9 09:48:05 2013	(r254137)
+++ head/sys/amd64/amd64/pmap.c	Fri Aug  9 11:11:11 2013	(r254138)
@@ -3498,7 +3498,7 @@ pmap_enter(pmap_t pmap, vm_offset_t va, 
 	KASSERT((m->oflags & VPO_UNMANAGED) != 0 || va < kmi.clean_sva ||
 	    va >= kmi.clean_eva,
 	    ("pmap_enter: managed mapping within the clean submap"));
-	if ((m->oflags & (VPO_UNMANAGED | VPO_BUSY)) == 0)
+	if ((m->oflags & VPO_UNMANAGED) == 0 && !vm_page_xbusied(m))
 		VM_OBJECT_ASSERT_WLOCKED(m->object);
 	pa = VM_PAGE_TO_PHYS(m);
 	newpte = (pt_entry_t)(pa | PG_A | PG_V);
@@ -4609,13 +4609,12 @@ pmap_is_modified(vm_page_t m)
 	    ("pmap_is_modified: page %p is not managed", m));
 
 	/*
-	 * If the page is not VPO_BUSY, then PGA_WRITEABLE cannot be
+	 * If the page is not exclusive busied, then PGA_WRITEABLE cannot be
 	 * concurrently set while the object is locked.  Thus, if PGA_WRITEABLE
 	 * is clear, no PTEs can have PG_M set.
 	 */
 	VM_OBJECT_ASSERT_WLOCKED(m->object);
-	if ((m->oflags & VPO_BUSY) == 0 &&
-	    (m->aflags & PGA_WRITEABLE) == 0)
+	if (!vm_page_xbusied(m) && (m->aflags & PGA_WRITEABLE) == 0)
 		return (FALSE);
 	rw_wlock(&pvh_global_lock);
 	rv = pmap_is_modified_pvh(&m->md) ||
@@ -4740,13 +4739,12 @@ pmap_remove_write(vm_page_t m)
 	    ("pmap_remove_write: page %p is not managed", m));
 
 	/*
-	 * If the page is not VPO_BUSY, then PGA_WRITEABLE cannot be set by
-	 * another thread while the object is locked.  Thus, if PGA_WRITEABLE
-	 * is clear, no page table entries need updating.
+	 * If the page is not exclusive busied, then PGA_WRITEABLE cannot be
+	 * set by another thread while the object is locked.  Thus,
+	 * if PGA_WRITEABLE is clear, no page table entries need updating.
 	 */
 	VM_OBJECT_ASSERT_WLOCKED(m->object);
-	if ((m->oflags & VPO_BUSY) == 0 &&
-	    (m->aflags & PGA_WRITEABLE) == 0)
+	if (!vm_page_xbusied(m) && (m->aflags & PGA_WRITEABLE) == 0)
 		return;
 	rw_wlock(&pvh_global_lock);
 	if ((m->flags & PG_FICTITIOUS) != 0)
@@ -4924,13 +4922,13 @@ pmap_clear_modify(vm_page_t m)
 	KASSERT((m->oflags & VPO_UNMANAGED) == 0,
 	    ("pmap_clear_modify: page %p is not managed", m));
 	VM_OBJECT_ASSERT_WLOCKED(m->object);
-	KASSERT((m->oflags & VPO_BUSY) == 0,
-	    ("pmap_clear_modify: page %p is busy", m));
+	KASSERT(!vm_page_xbusied(m),
+	    ("pmap_clear_modify: page %p is exclusive busied", m));
 
 	/*
 	 * If the page is not PGA_WRITEABLE, then no PTEs can have PG_M set.
 	 * If the object containing the page is locked and the page is not
-	 * VPO_BUSY, then PGA_WRITEABLE cannot be concurrently set.
+	 * exclusive busied, then PGA_WRITEABLE cannot be concurrently set.
 	 */
 	if ((m->aflags & PGA_WRITEABLE) == 0)
 		return;

Modified: head/sys/arm/arm/pmap-v6.c
==============================================================================
--- head/sys/arm/arm/pmap-v6.c	Fri Aug  9 09:48:05 2013	(r254137)
+++ head/sys/arm/arm/pmap-v6.c	Fri Aug  9 11:11:11 2013	(r254138)
@@ -2670,8 +2670,8 @@ pmap_enter_locked(pmap_t pmap, vm_offset
 		pa = systempage.pv_pa;
 		m = NULL;
 	} else {
-		KASSERT((m->oflags & (VPO_UNMANAGED | VPO_BUSY)) != 0 ||
-		    (flags & M_NOWAIT) != 0,
+		KASSERT((m->oflags & VPO_UNMANAGED) != 0 ||
+		    vm_page_xbusied(m) || (flags & M_NOWAIT) != 0,
 		    ("pmap_enter_locked: page %p is not busy", m));
 		pa = VM_PAGE_TO_PHYS(m);
 	}
@@ -3934,13 +3934,12 @@ pmap_is_modified(vm_page_t m)
 	    ("pmap_is_modified: page %p is not managed", m));
 	rv = FALSE;
 	/*
-	 * If the page is not VPO_BUSY, then PGA_WRITEABLE cannot be
+	 * If the page is not exclusive busied, then PGA_WRITEABLE cannot be
 	 * concurrently set while the object is locked.  Thus, if PGA_WRITEABLE
 	 * is clear, no PTEs can have PG_M set.
 	 */
 	VM_OBJECT_ASSERT_WLOCKED(m->object);
-	if ((m->oflags & VPO_BUSY) == 0 &&
-	    (m->aflags & PGA_WRITEABLE) == 0)
+	if (!vm_page_xbusied(m) && (m->aflags & PGA_WRITEABLE) == 0)
 		return (rv);
 	rw_wlock(&pvh_global_lock);
 	TAILQ_FOREACH(pv, &m->md.pv_list, pv_list) {
@@ -3968,13 +3967,13 @@ pmap_clear_modify(vm_page_t m)
 	KASSERT((m->oflags & VPO_UNMANAGED) == 0,
 	    ("pmap_clear_modify: page %p is not managed", m));
 	VM_OBJECT_ASSERT_WLOCKED(m->object);
-	KASSERT((m->oflags & VPO_BUSY) == 0,
-	    ("pmap_clear_modify: page %p is busy", m));
+	KASSERT(!vm_page_xbusied(m),
+	    ("pmap_clear_modify: page %p is exclusive busied", m));
 
 	/*
 	 * If the page is not PGA_WRITEABLE, then no mappings can be modified.
 	 * If the object containing the page is locked and the page is not
-	 * VPO_BUSY, then PGA_WRITEABLE cannot be concurrently set.
+	 * exclusive busied, then PGA_WRITEABLE cannot be concurrently set.
 	 */
 	if ((m->aflags & PGA_WRITEABLE) == 0)
 		return;
@@ -4009,13 +4008,12 @@ pmap_remove_write(vm_page_t m)
 	    ("pmap_remove_write: page %p is not managed", m));
 
 	/*
-	 * If the page is not VPO_BUSY, then PGA_WRITEABLE cannot be set by
-	 * another thread while the object is locked.  Thus, if PGA_WRITEABLE
-	 * is clear, no page table entries need updating.
+	 * If the page is not exclusive busied, then PGA_WRITEABLE cannot be
+	 * set by another thread while the object is locked.  Thus,
+	 * if PGA_WRITEABLE is clear, no page table entries need updating.
 	 */
 	VM_OBJECT_ASSERT_WLOCKED(m->object);
-	if ((m->oflags & VPO_BUSY) != 0 ||
-	    (m->aflags & PGA_WRITEABLE) != 0)
+	if (vm_page_xbusied(m) || (m->aflags & PGA_WRITEABLE) != 0)
 		pmap_clearbit(m, PVF_WRITE);
 }
 

Modified: head/sys/arm/arm/pmap.c
==============================================================================
--- head/sys/arm/arm/pmap.c	Fri Aug  9 09:48:05 2013	(r254137)
+++ head/sys/arm/arm/pmap.c	Fri Aug  9 11:11:11 2013	(r254138)
@@ -3319,8 +3319,8 @@ pmap_enter_locked(pmap_t pmap, vm_offset
 		pa = systempage.pv_pa;
 		m = NULL;
 	} else {
-		KASSERT((m->oflags & (VPO_UNMANAGED | VPO_BUSY)) != 0 ||
-		    (flags & M_NOWAIT) != 0,
+		KASSERT((m->oflags & VPO_UNMANAGED) != 0 ||
+		    vm_page_xbusied(m) || (flags & M_NOWAIT) != 0,
 		    ("pmap_enter_locked: page %p is not busy", m));
 		pa = VM_PAGE_TO_PHYS(m);
 	}
@@ -4555,13 +4555,13 @@ pmap_clear_modify(vm_page_t m)
 	KASSERT((m->oflags & VPO_UNMANAGED) == 0,
 	    ("pmap_clear_modify: page %p is not managed", m));
 	VM_OBJECT_ASSERT_WLOCKED(m->object);
-	KASSERT((m->oflags & VPO_BUSY) == 0,
-	    ("pmap_clear_modify: page %p is busy", m));
+	KASSERT(!vm_page_xbusied(m),
+	    ("pmap_clear_modify: page %p is exclusive busied", m));
 
 	/*
 	 * If the page is not PGA_WRITEABLE, then no mappings can be modified.
 	 * If the object containing the page is locked and the page is not
-	 * VPO_BUSY, then PGA_WRITEABLE cannot be concurrently set.
+	 * exclusive busied, then PGA_WRITEABLE cannot be concurrently set.
 	 */
 	if ((m->aflags & PGA_WRITEABLE) == 0)
 		return;
@@ -4612,13 +4612,12 @@ pmap_remove_write(vm_page_t m)
 	    ("pmap_remove_write: page %p is not managed", m));
 
 	/*
-	 * If the page is not VPO_BUSY, then PGA_WRITEABLE cannot be set by
-	 * another thread while the object is locked.  Thus, if PGA_WRITEABLE
-	 * is clear, no page table entries need updating.
+	 * If the page is not exclusive busied, then PGA_WRITEABLE cannot be
+	 * set by another thread while the object is locked.  Thus,
+	 * if PGA_WRITEABLE is clear, no page table entries need updating.
 	 */
 	VM_OBJECT_ASSERT_WLOCKED(m->object);
-	if ((m->oflags & VPO_BUSY) != 0 ||
-	    (m->aflags & PGA_WRITEABLE) != 0)
+	if (vm_page_xbusied(m) || (m->aflags & PGA_WRITEABLE) != 0)
 		pmap_clearbit(m, PVF_WRITE);
 }
 

Modified: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c
==============================================================================
--- head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c	Fri Aug  9 09:48:05 2013	(r254137)
+++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c	Fri Aug  9 11:11:11 2013	(r254138)
@@ -335,20 +335,24 @@ page_busy(vnode_t *vp, int64_t start, in
 	for (;;) {
 		if ((pp = vm_page_lookup(obj, OFF_TO_IDX(start))) != NULL &&
 		    pp->valid) {
-			if ((pp->oflags & VPO_BUSY) != 0) {
+			if (vm_page_xbusied(pp)) {
 				/*
 				 * Reference the page before unlocking and
 				 * sleeping so that the page daemon is less
 				 * likely to reclaim it.
 				 */
 				vm_page_reference(pp);
-				vm_page_sleep(pp, "zfsmwb");
+				vm_page_lock(pp);
+				zfs_vmobject_wunlock(obj);
+				vm_page_busy_sleep(pp, "zfsmwb");
+				zfs_vmobject_wlock(obj);
 				continue;
 			}
+			vm_page_sbusy(pp);
 		} else if (pp == NULL) {
 			pp = vm_page_alloc(obj, OFF_TO_IDX(start),
 			    VM_ALLOC_SYSTEM | VM_ALLOC_IFCACHED |
-			    VM_ALLOC_NOBUSY);
+			    VM_ALLOC_SBUSY);
 		} else {
 			ASSERT(pp != NULL && !pp->valid);
 			pp = NULL;
@@ -357,7 +361,6 @@ page_busy(vnode_t *vp, int64_t start, in
 		if (pp != NULL) {
 			ASSERT3U(pp->valid, ==, VM_PAGE_BITS_ALL);
 			vm_object_pip_add(obj, 1);
-			vm_page_io_start(pp);
 			pmap_remove_write(pp);
 			vm_page_clear_dirty(pp, off, nbytes);
 		}
@@ -370,7 +373,7 @@ static void
 page_unbusy(vm_page_t pp)
 {
 
-	vm_page_io_finish(pp);
+	vm_page_sunbusy(pp);
 	vm_object_pip_subtract(pp->object, 1);
 }
 
@@ -386,14 +389,17 @@ page_hold(vnode_t *vp, int64_t start)
 	for (;;) {
 		if ((pp = vm_page_lookup(obj, OFF_TO_IDX(start))) != NULL &&
 		    pp->valid) {
-			if ((pp->oflags & VPO_BUSY) != 0) {
+			if (vm_page_xbusied(pp)) {
 				/*
 				 * Reference the page before unlocking and
 				 * sleeping so that the page daemon is less
 				 * likely to reclaim it.
 				 */
 				vm_page_reference(pp);
-				vm_page_sleep(pp, "zfsmwb");
+				vm_page_lock(pp);
+				zfs_vmobject_wunlock(obj);
+				vm_page_busy_sleep(pp, "zfsmwb");
+				zfs_vmobject_wlock(obj);
 				continue;
 			}
 
@@ -467,7 +473,7 @@ update_pages(vnode_t *vp, int64_t start,
 			    ("zfs update_pages: unaligned data in putpages case"));
 			KASSERT(pp->valid == VM_PAGE_BITS_ALL,
 			    ("zfs update_pages: invalid page in putpages case"));
-			KASSERT(pp->busy > 0,
+			KASSERT(vm_page_sbusied(pp),
 			    ("zfs update_pages: unbusy page in putpages case"));
 			KASSERT(!pmap_page_is_write_mapped(pp),
 			    ("zfs update_pages: writable page in putpages case"));
@@ -503,7 +509,7 @@ update_pages(vnode_t *vp, int64_t start,
  * ZFS to populate a range of page cache pages with data.
  *
  * NOTE: this function could be optimized to pre-allocate
- * all pages in advance, drain VPO_BUSY on all of them,
+ * all pages in advance, drain exclusive busy on all of them,
  * map them into contiguous KVA region and populate them
  * in one single dmu_read() call.
  */
@@ -531,10 +537,9 @@ mappedread_sf(vnode_t *vp, int nbytes, u
 	for (start = uio->uio_loffset; len > 0; start += PAGESIZE) {
 		int bytes = MIN(PAGESIZE, len);
 
-		pp = vm_page_grab(obj, OFF_TO_IDX(start), VM_ALLOC_NOBUSY |
+		pp = vm_page_grab(obj, OFF_TO_IDX(start), VM_ALLOC_SBUSY |
 		    VM_ALLOC_NORMAL | VM_ALLOC_RETRY | VM_ALLOC_IGN_SBUSY);
 		if (pp->valid == 0) {
-			vm_page_io_start(pp);
 			zfs_vmobject_wunlock(obj);
 			va = zfs_map_page(pp, &sf);
 			error = dmu_read(os, zp->z_id, start, bytes, va,
@@ -543,18 +548,19 @@ mappedread_sf(vnode_t *vp, int nbytes, u
 				bzero(va + bytes, PAGESIZE - bytes);
 			zfs_unmap_page(sf);
 			zfs_vmobject_wlock(obj);
-			vm_page_io_finish(pp);
+			vm_page_sunbusy(pp);
 			vm_page_lock(pp);
 			if (error) {
 				if (pp->wire_count == 0 && pp->valid == 0 &&
-				    pp->busy == 0 && !(pp->oflags & VPO_BUSY))
+				    !vm_page_busied(pp))
 					vm_page_free(pp);
 			} else {
 				pp->valid = VM_PAGE_BITS_ALL;
 				vm_page_activate(pp);
 			}
 			vm_page_unlock(pp);
-		}
+		} else
+			vm_page_sunbusy(pp);
 		if (error)
 			break;
 		uio->uio_resid -= bytes;

Modified: head/sys/dev/agp/agp.c
==============================================================================
--- head/sys/dev/agp/agp.c	Fri Aug  9 09:48:05 2013	(r254137)
+++ head/sys/dev/agp/agp.c	Fri Aug  9 11:11:11 2013	(r254138)
@@ -600,7 +600,7 @@ agp_generic_bind_memory(device_t dev, st
 				goto bad;
 			}
 		}
-		vm_page_wakeup(m);
+		vm_page_xunbusy(m);
 	}
 	VM_OBJECT_WUNLOCK(mem->am_obj);
 
@@ -627,7 +627,7 @@ bad:
 	for (k = 0; k < mem->am_size; k += PAGE_SIZE) {
 		m = vm_page_lookup(mem->am_obj, OFF_TO_IDX(k));
 		if (k >= i)
-			vm_page_wakeup(m);
+			vm_page_xunbusy(m);
 		vm_page_lock(m);
 		vm_page_unwire(m, 0);
 		vm_page_unlock(m);

Modified: head/sys/dev/drm2/i915/i915_gem.c
==============================================================================
--- head/sys/dev/drm2/i915/i915_gem.c	Fri Aug  9 09:48:05 2013	(r254137)
+++ head/sys/dev/drm2/i915/i915_gem.c	Fri Aug  9 11:11:11 2013	(r254138)
@@ -1356,9 +1356,8 @@ i915_gem_pager_fault(vm_object_t vm_obj,
 		*mres = NULL;
 	} else
 		oldm = NULL;
-retry:
 	VM_OBJECT_WUNLOCK(vm_obj);
-unlocked_vmobj:
+retry:
 	cause = ret = 0;
 	m = NULL;
 
@@ -1379,9 +1378,11 @@ unlocked_vmobj:
 	VM_OBJECT_WLOCK(vm_obj);
 	m = vm_page_lookup(vm_obj, OFF_TO_IDX(offset));
 	if (m != NULL) {
-		if ((m->flags & VPO_BUSY) != 0) {
+		if (vm_page_busied(m)) {
 			DRM_UNLOCK(dev);
-			vm_page_sleep(m, "915pee");
+			vm_page_lock(m);
+			VM_OBJECT_WUNLOCK(vm_obj);
+			vm_page_busy_sleep(m, "915pee");
 			goto retry;
 		}
 		goto have_page;
@@ -1435,16 +1436,18 @@ unlocked_vmobj:
 	    ("not fictitious %p", m));
 	KASSERT(m->wire_count == 1, ("wire_count not 1 %p", m));
 
-	if ((m->flags & VPO_BUSY) != 0) {
+	if (vm_page_busied(m)) {
 		DRM_UNLOCK(dev);
-		vm_page_sleep(m, "915pbs");
+		vm_page_lock(m);
+		VM_OBJECT_WUNLOCK(vm_obj);
+		vm_page_busy_sleep(m, "915pbs");
 		goto retry;
 	}
 	m->valid = VM_PAGE_BITS_ALL;
 	vm_page_insert(m, vm_obj, OFF_TO_IDX(offset));
 have_page:
 	*mres = m;
-	vm_page_busy(m);
+	vm_page_xbusy(m);
 
 	CTR4(KTR_DRM, "fault %p %jx %x phys %x", gem_obj, offset, prot,
 	    m->phys_addr);
@@ -1465,7 +1468,7 @@ out:
 	    -ret, cause);
 	if (ret == -EAGAIN || ret == -EIO || ret == -EINTR) {
 		kern_yield(PRI_USER);
-		goto unlocked_vmobj;
+		goto retry;
 	}
 	VM_OBJECT_WLOCK(vm_obj);
 	vm_object_pip_wakeup(vm_obj);
@@ -2330,7 +2333,7 @@ retry:
 			m = vm_page_lookup(devobj, i);
 			if (m == NULL)
 				continue;
-			if (vm_page_sleep_if_busy(m, true, "915unm"))
+			if (vm_page_sleep_if_busy(m, "915unm"))
 				goto retry;
 			cdev_pager_free_page(devobj, m);
 		}
@@ -2504,10 +2507,8 @@ i915_gem_wire_page(vm_object_t object, v
 	int rv;
 
 	VM_OBJECT_ASSERT_WLOCKED(object);
-	m = vm_page_grab(object, pindex, VM_ALLOC_NORMAL | VM_ALLOC_NOBUSY |
-	    VM_ALLOC_RETRY);
+	m = vm_page_grab(object, pindex, VM_ALLOC_NORMAL | VM_ALLOC_RETRY);
 	if (m->valid != VM_PAGE_BITS_ALL) {
-		vm_page_busy(m);
 		if (vm_pager_has_page(object, pindex, NULL, NULL)) {
 			rv = vm_pager_get_pages(object, &m, 1, 0);
 			m = vm_page_lookup(object, pindex);
@@ -2524,11 +2525,11 @@ i915_gem_wire_page(vm_object_t object, v
 			m->valid = VM_PAGE_BITS_ALL;
 			m->dirty = 0;
 		}
-		vm_page_wakeup(m);
 	}
 	vm_page_lock(m);
 	vm_page_wire(m);
 	vm_page_unlock(m);
+	vm_page_xunbusy(m);
 	atomic_add_long(&i915_gem_wired_pages_cnt, 1);
 	return (m);
 }

Modified: head/sys/dev/drm2/ttm/ttm_bo_vm.c
==============================================================================
--- head/sys/dev/drm2/ttm/ttm_bo_vm.c	Fri Aug  9 09:48:05 2013	(r254137)
+++ head/sys/dev/drm2/ttm/ttm_bo_vm.c	Fri Aug  9 11:11:11 2013	(r254138)
@@ -212,8 +212,11 @@ reserve:
 	}
 
 	VM_OBJECT_WLOCK(vm_obj);
-	if ((m->flags & VPO_BUSY) != 0) {
-		vm_page_sleep(m, "ttmpbs");
+	if (vm_page_busied(m)) {
+		vm_page_lock(m);
+		VM_OBJECT_WUNLOCK(vm_obj);
+		vm_page_busy_sleep(m, "ttmpbs");
+		VM_OBJECT_WLOCK(vm_obj);
 		ttm_mem_io_unlock(man);
 		ttm_bo_unreserve(bo);
 		goto retry;
@@ -228,7 +231,7 @@ reserve:
 		    ("inconsistent insert bo %p m %p m1 %p offset %jx",
 		    bo, m, m1, (uintmax_t)offset));
 	}
-	vm_page_busy(m);
+	vm_page_xbusy(m);
 
 	if (oldm != NULL) {
 		vm_page_lock(oldm);

Modified: head/sys/dev/drm2/ttm/ttm_tt.c
==============================================================================
--- head/sys/dev/drm2/ttm/ttm_tt.c	Fri Aug  9 09:48:05 2013	(r254137)
+++ head/sys/dev/drm2/ttm/ttm_tt.c	Fri Aug  9 11:11:11 2013	(r254138)
@@ -288,10 +288,8 @@ int ttm_tt_swapin(struct ttm_tt *ttm)
 	VM_OBJECT_WLOCK(obj);
 	vm_object_pip_add(obj, 1);
 	for (i = 0; i < ttm->num_pages; ++i) {
-		from_page = vm_page_grab(obj, i, VM_ALLOC_NOBUSY |
-		    VM_ALLOC_RETRY);
+		from_page = vm_page_grab(obj, i, VM_ALLOC_RETRY);
 		if (from_page->valid != VM_PAGE_BITS_ALL) {
-			vm_page_busy(from_page);
 			if (vm_pager_has_page(obj, i, NULL, NULL)) {
 				rv = vm_pager_get_pages(obj, &from_page, 1, 0);
 				if (rv != VM_PAGER_OK) {
@@ -303,8 +301,8 @@ int ttm_tt_swapin(struct ttm_tt *ttm)
 				}
 			} else
 				vm_page_zero_invalid(from_page, TRUE);
-			vm_page_wakeup(from_page);
 		}
+		vm_page_xunbusy(from_page);
 		to_page = ttm->pages[i];
 		if (unlikely(to_page == NULL)) {
 			ret = -ENOMEM;
@@ -357,7 +355,7 @@ int ttm_tt_swapout(struct ttm_tt *ttm, v
 		pmap_copy_page(from_page, to_page);
 		vm_page_dirty(to_page);
 		to_page->valid = VM_PAGE_BITS_ALL;
-		vm_page_wakeup(to_page);
+		vm_page_xunbusy(to_page);
 	}
 	vm_object_pip_wakeup(obj);
 	VM_OBJECT_WUNLOCK(obj);

Modified: head/sys/dev/md/md.c
==============================================================================
--- head/sys/dev/md/md.c	Fri Aug  9 09:48:05 2013	(r254137)
+++ head/sys/dev/md/md.c	Fri Aug  9 11:11:11 2013	(r254138)
@@ -834,7 +834,7 @@ mdstart_swap(struct md_s *sc, struct bio
 			else
 				rv = vm_pager_get_pages(sc->object, &m, 1, 0);
 			if (rv == VM_PAGER_ERROR) {
-				vm_page_wakeup(m);
+				vm_page_xunbusy(m);
 				break;
 			} else if (rv == VM_PAGER_FAIL) {
 				/*
@@ -859,7 +859,7 @@ mdstart_swap(struct md_s *sc, struct bio
 			else
 				rv = VM_PAGER_OK;
 			if (rv == VM_PAGER_ERROR) {
-				vm_page_wakeup(m);
+				vm_page_xunbusy(m);
 				break;
 			}
 			if ((bp->bio_flags & BIO_UNMAPPED) != 0) {
@@ -875,7 +875,7 @@ mdstart_swap(struct md_s *sc, struct bio
 			else
 				rv = VM_PAGER_OK;
 			if (rv == VM_PAGER_ERROR) {
-				vm_page_wakeup(m);
+				vm_page_xunbusy(m);
 				break;
 			}
 			if (len != PAGE_SIZE) {
@@ -885,7 +885,7 @@ mdstart_swap(struct md_s *sc, struct bio
 			} else
 				vm_pager_page_unswapped(m);
 		}
-		vm_page_wakeup(m);
+		vm_page_xunbusy(m);
 		vm_page_lock(m);
 		if (bp->bio_cmd == BIO_DELETE && len == PAGE_SIZE)
 			vm_page_free(m);

Modified: head/sys/fs/fuse/fuse_vnops.c
==============================================================================
--- head/sys/fs/fuse/fuse_vnops.c	Fri Aug  9 09:48:05 2013	(r254137)
+++ head/sys/fs/fuse/fuse_vnops.c	Fri Aug  9 11:11:11 2013	(r254138)
@@ -1854,36 +1854,8 @@ fuse_vnop_getpages(struct vop_getpages_a
 			 */
 			;
 		}
-		if (i != ap->a_reqpage) {
-			/*
-			 * Whether or not to leave the page activated is up in
-			 * the air, but we should put the page on a page queue
-			 * somewhere (it already is in the object).  Result:
-			 * It appears that emperical results show that
-			 * deactivating pages is best.
-			 */
-
-			/*
-			 * Just in case someone was asking for this page we
-			 * now tell them that it is ok to use.
-			 */
-			if (!error) {
-				if (m->oflags & VPO_WANTED) {
-					fuse_vm_page_lock(m);
-					vm_page_activate(m);
-					fuse_vm_page_unlock(m);
-				} else {
-					fuse_vm_page_lock(m);
-					vm_page_deactivate(m);
-					fuse_vm_page_unlock(m);
-				}
-				vm_page_wakeup(m);
-			} else {
-				fuse_vm_page_lock(m);
-				vm_page_free(m);
-				fuse_vm_page_unlock(m);
-			}
-		}
+		if (i != ap->a_reqpage)
+			vm_page_readahead_finish(m);
 	}
 	fuse_vm_page_unlock_queues();
 	VM_OBJECT_WUNLOCK(vp->v_object);

Modified: head/sys/fs/tmpfs/tmpfs_subr.c
==============================================================================
--- head/sys/fs/tmpfs/tmpfs_subr.c	Fri Aug  9 09:48:05 2013	(r254137)
+++ head/sys/fs/tmpfs/tmpfs_subr.c	Fri Aug  9 11:11:11 2013	(r254138)
@@ -1355,11 +1355,8 @@ tmpfs_reg_resize(struct vnode *vp, off_t
 retry:
 			m = vm_page_lookup(uobj, idx);
 			if (m != NULL) {
-				if ((m->oflags & VPO_BUSY) != 0 ||
-				    m->busy != 0) {
-					vm_page_sleep(m, "tmfssz");
+				if (vm_page_sleep_if_busy(m, "tmfssz"))
 					goto retry;
-				}
 				MPASS(m->valid == VM_PAGE_BITS_ALL);
 			} else if (vm_pager_has_page(uobj, idx, NULL, NULL)) {
 				m = vm_page_alloc(uobj, idx, VM_ALLOC_NORMAL);
@@ -1379,7 +1376,7 @@ retry:
 				if (rv == VM_PAGER_OK) {
 					vm_page_deactivate(m);
 					vm_page_unlock(m);
-					vm_page_wakeup(m);
+					vm_page_xunbusy(m);
 				} else {
 					vm_page_free(m);
 					vm_page_unlock(m);

Modified: head/sys/fs/tmpfs/tmpfs_vnops.c
==============================================================================
--- head/sys/fs/tmpfs/tmpfs_vnops.c	Fri Aug  9 09:48:05 2013	(r254137)
+++ head/sys/fs/tmpfs/tmpfs_vnops.c	Fri Aug  9 11:11:11 2013	(r254138)
@@ -449,7 +449,7 @@ tmpfs_nocacheread(vm_object_t tobj, vm_p
 
 	/*
 	 * Parallel reads of the page content from disk are prevented
-	 * by VPO_BUSY.
+	 * by exclusive busy.
 	 *
 	 * Although the tmpfs vnode lock is held here, it is
 	 * nonetheless safe to sleep waiting for a free page.  The
@@ -457,10 +457,8 @@ tmpfs_nocacheread(vm_object_t tobj, vm_p
 	 * lock to page out tobj's pages because tobj is a OBJT_SWAP
 	 * type object.
 	 */
-	m = vm_page_grab(tobj, idx, VM_ALLOC_NORMAL | VM_ALLOC_RETRY |
-	    VM_ALLOC_NOBUSY);
+	m = vm_page_grab(tobj, idx, VM_ALLOC_NORMAL | VM_ALLOC_RETRY);
 	if (m->valid != VM_PAGE_BITS_ALL) {
-		vm_page_busy(m);
 		if (vm_pager_has_page(tobj, idx, NULL, NULL)) {
 			rv = vm_pager_get_pages(tobj, &m, 1, 0);
 			m = vm_page_lookup(tobj, idx);
@@ -483,8 +481,8 @@ tmpfs_nocacheread(vm_object_t tobj, vm_p
 			}
 		} else
 			vm_page_zero_invalid(m, TRUE);
-		vm_page_wakeup(m);
 	}
+	vm_page_xunbusy(m);
 	vm_page_lock(m);
 	vm_page_hold(m);
 	vm_page_unlock(m);
@@ -574,10 +572,8 @@ tmpfs_mappedwrite(vm_object_t tobj, size
 	tlen = MIN(PAGE_SIZE - offset, len);
 
 	VM_OBJECT_WLOCK(tobj);
-	tpg = vm_page_grab(tobj, idx, VM_ALLOC_NORMAL | VM_ALLOC_NOBUSY |
-	    VM_ALLOC_RETRY);
+	tpg = vm_page_grab(tobj, idx, VM_ALLOC_NORMAL | VM_ALLOC_RETRY);
 	if (tpg->valid != VM_PAGE_BITS_ALL) {
-		vm_page_busy(tpg);
 		if (vm_pager_has_page(tobj, idx, NULL, NULL)) {
 			rv = vm_pager_get_pages(tobj, &tpg, 1, 0);
 			tpg = vm_page_lookup(tobj, idx);
@@ -600,8 +596,8 @@ tmpfs_mappedwrite(vm_object_t tobj, size
 			}
 		} else
 			vm_page_zero_invalid(tpg, TRUE);
-		vm_page_wakeup(tpg);
 	}
+	vm_page_xunbusy(tpg);
 	vm_page_lock(tpg);
 	vm_page_hold(tpg);
 	vm_page_unlock(tpg);

Modified: head/sys/i386/i386/pmap.c
==============================================================================
--- head/sys/i386/i386/pmap.c	Fri Aug  9 09:48:05 2013	(r254137)
+++ head/sys/i386/i386/pmap.c	Fri Aug  9 11:11:11 2013	(r254138)
@@ -3459,7 +3459,7 @@ pmap_enter(pmap_t pmap, vm_offset_t va, 
 	KASSERT(va < UPT_MIN_ADDRESS || va >= UPT_MAX_ADDRESS,
 	    ("pmap_enter: invalid to pmap_enter page table pages (va: 0x%x)",
 	    va));
-	if ((m->oflags & (VPO_UNMANAGED | VPO_BUSY)) == 0)
+	if ((m->oflags & VPO_UNMANAGED) == 0 && !vm_page_xbusied(m))
 		VM_OBJECT_ASSERT_WLOCKED(m->object);
 
 	mpte = NULL;
@@ -4553,13 +4553,12 @@ pmap_is_modified(vm_page_t m)
 	    ("pmap_is_modified: page %p is not managed", m));
 
 	/*
-	 * If the page is not VPO_BUSY, then PGA_WRITEABLE cannot be
+	 * If the page is not exclusive busied, then PGA_WRITEABLE cannot be
 	 * concurrently set while the object is locked.  Thus, if PGA_WRITEABLE
 	 * is clear, no PTEs can have PG_M set.
 	 */
 	VM_OBJECT_ASSERT_WLOCKED(m->object);
-	if ((m->oflags & VPO_BUSY) == 0 &&
-	    (m->aflags & PGA_WRITEABLE) == 0)
+	if (!vm_page_xbusied(m) && (m->aflags & PGA_WRITEABLE) == 0)
 		return (FALSE);
 	rw_wlock(&pvh_global_lock);
 	rv = pmap_is_modified_pvh(&m->md) ||
@@ -4688,13 +4687,12 @@ pmap_remove_write(vm_page_t m)
 	    ("pmap_remove_write: page %p is not managed", m));
 
 	/*
-	 * If the page is not VPO_BUSY, then PGA_WRITEABLE cannot be set by
-	 * another thread while the object is locked.  Thus, if PGA_WRITEABLE
-	 * is clear, no page table entries need updating.
+	 * If the page is not exclusive busied, then PGA_WRITEABLE cannot be
+	 * set by another thread while the object is locked.  Thus,
+	 * if PGA_WRITEABLE is clear, no page table entries need updating.
 	 */
 	VM_OBJECT_ASSERT_WLOCKED(m->object);
-	if ((m->oflags & VPO_BUSY) == 0 &&
-	    (m->aflags & PGA_WRITEABLE) == 0)
+	if (!vm_page_xbusied(m) && (m->aflags & PGA_WRITEABLE) == 0)
 		return;
 	rw_wlock(&pvh_global_lock);
 	sched_pin();
@@ -4845,13 +4843,13 @@ pmap_clear_modify(vm_page_t m)
 	KASSERT((m->oflags & VPO_UNMANAGED) == 0,
 	    ("pmap_clear_modify: page %p is not managed", m));
 	VM_OBJECT_ASSERT_WLOCKED(m->object);
-	KASSERT((m->oflags & VPO_BUSY) == 0,
-	    ("pmap_clear_modify: page %p is busy", m));
+	KASSERT(!vm_page_xbusied(m),
+	    ("pmap_clear_modify: page %p is exclusive busied", m));
 
 	/*
 	 * If the page is not PGA_WRITEABLE, then no PTEs can have PG_M set.
 	 * If the object containing the page is locked and the page is not
-	 * VPO_BUSY, then PGA_WRITEABLE cannot be concurrently set.

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***


More information about the svn-src-head mailing list