cvs commit: src/sys/vm vm_fault.c

Brian Fundakowski Feldman green at FreeBSD.org
Sat Aug 21 15:59:42 PDT 2004


On Sat, Aug 21, 2004 at 07:20:21PM +0000, Alan Cox wrote:
> alc         2004-08-21 19:20:21 UTC
> 
>   FreeBSD src repository
> 
>   Modified files:
>     sys/vm               vm_fault.c 
>   Log:
>   Further reduce the use of Giant by vm_fault(): Giant is held only when
>   manipulating a vnode, e.g., calling vput().  This reduces contention for
>   Giant during many copy-on-write faults, resulting in some additional
>   speedup on SMPs.
>   
>   Note: debug_mpsafevm must be enabled for this optimization to take effect.

This is very broken.  See included first attempt at fixing it without
regard for actually trying to reimplement debug.mpsafenet for vnodes.

Index: vm_fault.c
===================================================================
RCS file: /usr/ncvs/src/sys/vm/vm_fault.c,v
retrieving revision 1.193
diff -u -r1.193 vm_fault.c
--- vm_fault.c	21 Aug 2004 19:20:21 -0000	1.193
+++ vm_fault.c	21 Aug 2004 22:31:57 -0000
@@ -172,8 +172,6 @@
 		mtx_unlock(&Giant);
 		fs->vp = NULL;
 	}
-	if (dealloc)
-		VM_UNLOCK_GIANT();
 }
 
 #define unlock_things(fs) _unlock_things(fs, 0)
@@ -231,11 +229,13 @@
 	 * search.
 	 */
 	fs.map = map;
+	mtx_lock(&Giant);
 	result = vm_map_lookup(&fs.map, vaddr, fault_type, &fs.entry,
 	    &fs.first_object, &fs.first_pindex, &prot, &wired);
 	if (result != KERN_SUCCESS) {
 		if (result != KERN_PROTECTION_FAILURE ||
 		    (fault_flags & VM_FAULT_WIRE_MASK) != VM_FAULT_USER_WIRE) {
+			mtx_unlock(&Giant);
 			if (growstack && result == KERN_INVALID_ADDRESS &&
 			    map != kernel_map && curproc != NULL) {
 				result = vm_map_growstack(curproc, vaddr);
@@ -257,8 +257,10 @@
 		result = vm_map_lookup(&fs.map, vaddr,
 			VM_PROT_READ|VM_PROT_WRITE|VM_PROT_OVERRIDE_WRITE,
 			&fs.entry, &fs.first_object, &fs.first_pindex, &prot, &wired);
-		if (result != KERN_SUCCESS)
+		if (result != KERN_SUCCESS) {
+			mtx_unlock(&Giant);
 			return (result);
+		}
 
 		/*
 		 * If we don't COW now, on a user wire, the user will never
@@ -291,7 +293,6 @@
 	 *
 	 * XXX vnode_pager_lock() can block without releasing the map lock.
 	 */
-	mtx_lock(&Giant);
 	VM_OBJECT_LOCK(fs.first_object);
 	vm_object_reference_locked(fs.first_object);
 	fs.vp = vnode_pager_lock(fs.first_object);
@@ -368,7 +369,6 @@
 				if (!vm_page_sleep_if_busy(fs.m, TRUE, "vmpfw"))
 					vm_page_unlock_queues();
 				atomic_add_int(&cnt.v_intrans, 1);
-				VM_UNLOCK_GIANT();
 				vm_object_deallocate(fs.first_object);
 				goto RetryFault;
 			}

-- 
Brian Fundakowski Feldman                           \'[ FreeBSD ]''''''''''\
  <> green at FreeBSD.org                               \  The Power to Serve! \
 Opinions expressed are my own.                       \,,,,,,,,,,,,,,,,,,,,,,\


More information about the cvs-all mailing list