svn commit: r248629 - in user/attilio/vmobj-readlock/sys: dev/agp dev/drm2/i915 dev/md fs/fuse fs/tmpfs kern vm

Attilio Rao attilio at FreeBSD.org
Fri Mar 22 22:52:05 UTC 2013


Author: attilio
Date: Fri Mar 22 22:52:02 2013
New Revision: 248629
URL: http://svnweb.freebsd.org/changeset/base/248629

Log:
  - Save some further atomics and introduce vm_page_wakeup_locked() that
    assumes vm_page_lock held.  It is implemented as an hard function
    right now because it is only a WIP and it avoids a namespace
    pollution.  It will be cleaned before to merge back.
    Maybe it makes sense to always acquire the vm_page_lock() in the
    users for vm_page_wakeup() and get rid of vm_page_wakeup_locked()
    finally.  This will be discussed more.
  - Fix a bug where vm_page_remove() is called for UNNAMED pages and
    the page lock is not held.  Don't make assumption about the lock in
    that case and just deal with the situation, even if it is a tricky
    pattern. We use a boolean_t rather than a mtx pointer. [0]
  
  Sponsored by:	EMC / Isilon storage division
  [0] Reported by:	pho

Modified:
  user/attilio/vmobj-readlock/sys/dev/agp/agp.c
  user/attilio/vmobj-readlock/sys/dev/drm2/i915/i915_gem.c
  user/attilio/vmobj-readlock/sys/dev/md/md.c
  user/attilio/vmobj-readlock/sys/fs/fuse/fuse_vnops.c
  user/attilio/vmobj-readlock/sys/fs/tmpfs/tmpfs_subr.c
  user/attilio/vmobj-readlock/sys/fs/tmpfs/tmpfs_vnops.c
  user/attilio/vmobj-readlock/sys/kern/kern_exec.c
  user/attilio/vmobj-readlock/sys/kern/uipc_shm.c
  user/attilio/vmobj-readlock/sys/vm/swap_pager.c
  user/attilio/vmobj-readlock/sys/vm/vm_fault.c
  user/attilio/vmobj-readlock/sys/vm/vm_glue.c
  user/attilio/vmobj-readlock/sys/vm/vm_page.c
  user/attilio/vmobj-readlock/sys/vm/vm_page.h

Modified: user/attilio/vmobj-readlock/sys/dev/agp/agp.c
==============================================================================
--- user/attilio/vmobj-readlock/sys/dev/agp/agp.c	Fri Mar 22 22:50:48 2013	(r248628)
+++ user/attilio/vmobj-readlock/sys/dev/agp/agp.c	Fri Mar 22 22:52:02 2013	(r248629)
@@ -626,9 +626,9 @@ bad:
 	VM_OBJECT_ASSERT_WLOCKED(mem->am_obj);
 	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_lock(m);
+		if (k >= i)
+			vm_page_wakeup_locked(m);
 		vm_page_unwire(m, 0);
 		vm_page_unlock(m);
 	}

Modified: user/attilio/vmobj-readlock/sys/dev/drm2/i915/i915_gem.c
==============================================================================
--- user/attilio/vmobj-readlock/sys/dev/drm2/i915/i915_gem.c	Fri Mar 22 22:50:48 2013	(r248628)
+++ user/attilio/vmobj-readlock/sys/dev/drm2/i915/i915_gem.c	Fri Mar 22 22:52:02 2013	(r248629)
@@ -2516,8 +2516,8 @@ i915_gem_wire_page(vm_object_t object, v
 	}
 	vm_page_lock(m);
 	vm_page_wire(m);
+	vm_page_wakeup_locked(m);
 	vm_page_unlock(m);
-	vm_page_wakeup(m);
 	atomic_add_long(&i915_gem_wired_pages_cnt, 1);
 	return (m);
 }

Modified: user/attilio/vmobj-readlock/sys/dev/md/md.c
==============================================================================
--- user/attilio/vmobj-readlock/sys/dev/md/md.c	Fri Mar 22 22:50:48 2013	(r248628)
+++ user/attilio/vmobj-readlock/sys/dev/md/md.c	Fri Mar 22 22:52:02 2013	(r248629)
@@ -879,8 +879,8 @@ mdstart_swap(struct md_s *sc, struct bio
 			} else
 				vm_pager_page_unswapped(m);
 		}
-		vm_page_wakeup(m);
 		vm_page_lock(m);
+		vm_page_wakeup_locked(m);
 		if (bp->bio_cmd == BIO_DELETE && len == PAGE_SIZE)
 			vm_page_free(m);
 		else

Modified: user/attilio/vmobj-readlock/sys/fs/fuse/fuse_vnops.c
==============================================================================
--- user/attilio/vmobj-readlock/sys/fs/fuse/fuse_vnops.c	Fri Mar 22 22:50:48 2013	(r248628)
+++ user/attilio/vmobj-readlock/sys/fs/fuse/fuse_vnops.c	Fri Mar 22 22:52:02 2013	(r248629)
@@ -1873,8 +1873,8 @@ fuse_vnop_getpages(struct vop_getpages_a
 					vm_page_activate(m);
 				else
 					vm_page_deactivate(m);
+				vm_page_wakeup_locked(m);
 				fuse_vm_page_unlock(m);
-				vm_page_wakeup(m);
 			} else {
 				fuse_vm_page_lock(m);
 				vm_page_free(m);

Modified: user/attilio/vmobj-readlock/sys/fs/tmpfs/tmpfs_subr.c
==============================================================================
--- user/attilio/vmobj-readlock/sys/fs/tmpfs/tmpfs_subr.c	Fri Mar 22 22:50:48 2013	(r248628)
+++ user/attilio/vmobj-readlock/sys/fs/tmpfs/tmpfs_subr.c	Fri Mar 22 22:52:02 2013	(r248629)
@@ -1309,8 +1309,8 @@ retry:
 				vm_page_lock(m);
 				if (rv == VM_PAGER_OK) {
 					vm_page_deactivate(m);
+					vm_page_wakeup_locked(m);
 					vm_page_unlock(m);
-					vm_page_wakeup(m);
 				} else {
 					vm_page_free(m);
 					vm_page_unlock(m);

Modified: user/attilio/vmobj-readlock/sys/fs/tmpfs/tmpfs_vnops.c
==============================================================================
--- user/attilio/vmobj-readlock/sys/fs/tmpfs/tmpfs_vnops.c	Fri Mar 22 22:50:48 2013	(r248628)
+++ user/attilio/vmobj-readlock/sys/fs/tmpfs/tmpfs_vnops.c	Fri Mar 22 22:52:02 2013	(r248629)
@@ -468,8 +468,8 @@ tmpfs_nocacheread(vm_object_t tobj, vm_p
 	VM_OBJECT_WLOCK(tobj);
 	vm_page_lock(m);
 	vm_page_unwire(m, TRUE);
+	vm_page_wakeup_locked(m);
 	vm_page_unlock(m);
-	vm_page_wakeup(m);
 	VM_OBJECT_WUNLOCK(tobj);
 
 	return (error);
@@ -696,8 +696,8 @@ lookupvpg:
 	}
 	vm_page_lock(tpg);
 	vm_page_unwire(tpg, TRUE);
+	vm_page_wakeup_locked(tpg);
 	vm_page_unlock(tpg);
-	vm_page_wakeup(tpg);
 out:
 	VM_OBJECT_WUNLOCK(tobj);
 	if (vpg != NULL) {

Modified: user/attilio/vmobj-readlock/sys/kern/kern_exec.c
==============================================================================
--- user/attilio/vmobj-readlock/sys/kern/kern_exec.c	Fri Mar 22 22:50:48 2013	(r248628)
+++ user/attilio/vmobj-readlock/sys/kern/kern_exec.c	Fri Mar 22 22:52:02 2013	(r248629)
@@ -971,8 +971,8 @@ exec_map_first_page(imgp)
 	}
 	vm_page_lock(ma[0]);
 	vm_page_hold(ma[0]);
+	vm_page_wakeup_locked(ma[0]);
 	vm_page_unlock(ma[0]);
-	vm_page_wakeup(ma[0]);
 	VM_OBJECT_WUNLOCK(object);
 
 	imgp->firstpage = sf_buf_alloc(ma[0], 0);

Modified: user/attilio/vmobj-readlock/sys/kern/uipc_shm.c
==============================================================================
--- user/attilio/vmobj-readlock/sys/kern/uipc_shm.c	Fri Mar 22 22:50:48 2013	(r248628)
+++ user/attilio/vmobj-readlock/sys/kern/uipc_shm.c	Fri Mar 22 22:52:02 2013	(r248629)
@@ -307,8 +307,8 @@ retry:
 				vm_page_lock(m);
 				if (rv == VM_PAGER_OK) {
 					vm_page_deactivate(m);
+					vm_page_wakeup_locked(m);
 					vm_page_unlock(m);
-					vm_page_wakeup(m);
 				} else {
 					vm_page_free(m);
 					vm_page_unlock(m);

Modified: user/attilio/vmobj-readlock/sys/vm/swap_pager.c
==============================================================================
--- user/attilio/vmobj-readlock/sys/vm/swap_pager.c	Fri Mar 22 22:50:48 2013	(r248628)
+++ user/attilio/vmobj-readlock/sys/vm/swap_pager.c	Fri Mar 22 22:52:02 2013	(r248629)
@@ -1597,8 +1597,8 @@ swp_pager_async_iodone(struct buf *bp)
 			if (i != bp->b_pager.pg_reqpage) {
 				vm_page_lock(m);
 				vm_page_deactivate(m);
+				vm_page_wakeup_locked(m);
 				vm_page_unlock(m);
-				vm_page_wakeup(m);
 			} else {
 				vm_page_lock(m);
 				vm_page_flash(m);
@@ -1718,8 +1718,8 @@ swp_pager_force_pagein(vm_object_t objec
 		vm_page_dirty(m);
 		vm_page_lock(m);
 		vm_page_activate(m);
+		vm_page_wakeup_locked(m);
 		vm_page_unlock(m);
-		vm_page_wakeup(m);
 		vm_pager_page_unswapped(m);
 		return;
 	}
@@ -1730,8 +1730,8 @@ swp_pager_force_pagein(vm_object_t objec
 	vm_page_dirty(m);
 	vm_page_lock(m);
 	vm_page_deactivate(m);
+	vm_page_wakeup_locked(m);
 	vm_page_unlock(m);
-	vm_page_wakeup(m);
 	vm_pager_page_unswapped(m);
 }
 

Modified: user/attilio/vmobj-readlock/sys/vm/vm_fault.c
==============================================================================
--- user/attilio/vmobj-readlock/sys/vm/vm_fault.c	Fri Mar 22 22:50:48 2013	(r248628)
+++ user/attilio/vmobj-readlock/sys/vm/vm_fault.c	Fri Mar 22 22:52:02 2013	(r248629)
@@ -141,8 +141,8 @@ static inline void
 release_page(struct faultstate *fs)
 {
 
-	vm_page_wakeup(fs->m);
 	vm_page_lock(fs->m);
+	vm_page_wakeup_locked(fs->m);
 	vm_page_deactivate(fs->m);
 	vm_page_unlock(fs->m);
 	fs->m = NULL;
@@ -934,8 +934,8 @@ vnode_locked:
 		*m_hold = fs.m;
 		vm_page_hold(fs.m);
 	}
+	vm_page_wakeup_locked(fs.m);
 	vm_page_unlock(fs.m);
-	vm_page_wakeup(fs.m);
 
 	/*
 	 * Unlock everything, and return
@@ -1361,13 +1361,14 @@ vm_fault_copy_entry(vm_map_t dst_map, vm
 
 			vm_page_lock(dst_m);
 			vm_page_wire(dst_m);
+			vm_page_wakeup_locked(dst_m);
 			vm_page_unlock(dst_m);
 		} else {
 			vm_page_lock(dst_m);
 			vm_page_activate(dst_m);
+			vm_page_wakeup_locked(dst_m);
 			vm_page_unlock(dst_m);
 		}
-		vm_page_wakeup(dst_m);
 	}
 	VM_OBJECT_WUNLOCK(dst_object);
 	if (upgrade) {

Modified: user/attilio/vmobj-readlock/sys/vm/vm_glue.c
==============================================================================
--- user/attilio/vmobj-readlock/sys/vm/vm_glue.c	Fri Mar 22 22:50:48 2013	(r248628)
+++ user/attilio/vmobj-readlock/sys/vm/vm_glue.c	Fri Mar 22 22:52:02 2013	(r248629)
@@ -258,8 +258,8 @@ vm_imgact_hold_page(vm_object_t object, 
 	}
 	vm_page_lock(m);
 	vm_page_hold(m);
+	vm_page_wakeup_locked(m);
 	vm_page_unlock(m);
-	vm_page_wakeup(m);
 out:
 	VM_OBJECT_WUNLOCK(object);
 	return (m);

Modified: user/attilio/vmobj-readlock/sys/vm/vm_page.c
==============================================================================
--- user/attilio/vmobj-readlock/sys/vm/vm_page.c	Fri Mar 22 22:50:48 2013	(r248628)
+++ user/attilio/vmobj-readlock/sys/vm/vm_page.c	Fri Mar 22 22:52:02 2013	(r248629)
@@ -493,22 +493,39 @@ vm_page_flash(vm_page_t m)
 }
 
 /*
- *      vm_page_wakeup:
+ *	vm_page_wakeup:
+ *
+ *	clear the VPO_BUSY flag and wakeup anyone waiting for the
+ *	page.
+ *
+ *	The object containing the page must be locked.
+ */
+void
+vm_page_wakeup(vm_page_t m)
+{
+
+	vm_page_lock(m);
+	vm_page_wakeup_locked(m);
+	vm_page_unlock(m);
+}
+
+/*
+ *      vm_page_wakeup_locked:
  *
  *      clear the VPO_BUSY flag and wakeup anyone waiting for the
  *      page.
  *
+ *	The page and the object containing the page must be locked.
  */
 void
-vm_page_wakeup(vm_page_t m)
+vm_page_wakeup_locked(vm_page_t m)
 {
 
 	VM_OBJECT_ASSERT_WLOCKED(m->object);
+	vm_page_lock_assert(m, MA_OWNED);
 	KASSERT(m->oflags & VPO_BUSY, ("vm_page_wakeup: page not busy!!!"));
 	m->oflags &= ~VPO_BUSY;
-	vm_page_lock(m);
 	vm_page_flash(m);
-	vm_page_unlock(m);
 }
 
 void
@@ -729,8 +746,8 @@ vm_page_readahead_finish(vm_page_t m)
 			vm_page_activate(m);
 		else
 			vm_page_deactivate(m);
+		vm_page_wakeup_locked(m);
 		vm_page_unlock(m);
-		vm_page_wakeup(m);
 	} else {
 		/*
 		 * Free the completely invalid page.  Such page state
@@ -897,6 +914,7 @@ void
 vm_page_remove(vm_page_t m)
 {
 	vm_object_t object;
+	boolean_t lockacq;
 
 	if ((m->oflags & VPO_UNMANAGED) == 0)
 		vm_page_lock_assert(m, MA_OWNED);
@@ -905,7 +923,15 @@ vm_page_remove(vm_page_t m)
 	VM_OBJECT_ASSERT_WLOCKED(object);
 	if (m->oflags & VPO_BUSY) {
 		m->oflags &= ~VPO_BUSY;
+		lockacq = FALSE;
+		if ((m->oflags & VPO_UNMANAGED) != 0 &&
+		    !mtx_owned(vm_page_lockptr(m))) {
+			lockacq = TRUE;
+			vm_page_lock(m);
+		}
 		vm_page_flash(m);
+		if (lockacq)
+			vm_page_unlock(m);
 	}
 
 	/*

Modified: user/attilio/vmobj-readlock/sys/vm/vm_page.h
==============================================================================
--- user/attilio/vmobj-readlock/sys/vm/vm_page.h	Fri Mar 22 22:50:48 2013	(r248628)
+++ user/attilio/vmobj-readlock/sys/vm/vm_page.h	Fri Mar 22 22:52:02 2013	(r248629)
@@ -368,6 +368,7 @@ void vm_page_unhold(vm_page_t mem);
 void vm_page_free(vm_page_t m);
 void vm_page_free_zero(vm_page_t m);
 void vm_page_wakeup(vm_page_t m);
+void vm_page_wakeup_locked(vm_page_t m);
 
 void vm_page_activate (vm_page_t);
 vm_page_t vm_page_alloc (vm_object_t, vm_pindex_t, int);


More information about the svn-src-user mailing list