svn commit: r233853 - user/attilio/vmcontention/sys/fs/tmpfs

Attilio Rao attilio at FreeBSD.org
Tue Apr 3 20:07:44 UTC 2012


Author: attilio
Date: Tue Apr  3 20:07:43 2012
New Revision: 233853
URL: http://svn.freebsd.org/changeset/base/233853

Log:
  - It is wrong to skip tmpfs_mapped{read, write}() when the page cache
    is empty and nothing else is checked. Check that also the resident
    page pool is empty before to skip the operation.
  - Cleanup the cached page if it is found but the page is not active.
  
  Reported and tested by:	flo

Modified:
  user/attilio/vmcontention/sys/fs/tmpfs/tmpfs_vnops.c

Modified: user/attilio/vmcontention/sys/fs/tmpfs/tmpfs_vnops.c
==============================================================================
--- user/attilio/vmcontention/sys/fs/tmpfs/tmpfs_vnops.c	Tue Apr  3 20:06:07 2012	(r233852)
+++ user/attilio/vmcontention/sys/fs/tmpfs/tmpfs_vnops.c	Tue Apr  3 20:07:43 2012	(r233853)
@@ -514,7 +514,7 @@ tmpfs_mappedread(vm_object_t vobj, vm_ob
 		goto nocache;
 
 	VM_OBJECT_LOCK(vobj);
-	if (vobj->cached_page_count == 0) {
+	if (vobj->resident_page_count == 0 && vobj->cached_page_count == 0) {
 		VM_OBJECT_UNLOCK(vobj);
 		goto nocache;
 	}
@@ -647,31 +647,41 @@ tmpfs_mappedwrite(vm_object_t vobj, vm_o
 	}
 
 	VM_OBJECT_LOCK(vobj);
-	if (vobj->cached_page_count == 0) {
+	if (vobj->resident_page_count == 0 && vobj->cached_page_count == 0) {
 		VM_OBJECT_UNLOCK(vobj);
 		vpg = NULL;
 		goto nocache;
 	}
 lookupvpg:
-	if (((vpg = vm_page_lookup(vobj, idx)) != NULL) &&
-	    vm_page_is_valid(vpg, offset, tlen)) {
-		if ((vpg->oflags & VPO_BUSY) != 0) {
-			/*
-			 * Reference the page before unlocking and sleeping so
-			 * that the page daemon is less likely to reclaim it.  
-			 */
-			vm_page_reference(vpg);
-			vm_page_sleep(vpg, "tmfsmw");
-			goto lookupvpg;
+	vpg = vm_radix_lookup(&vobj->rtree, idx, VM_RADIX_ANY);
+	if (vpg != NULL) {
+		if (vm_page_is_valid(vpg, offset, tlen)) {
+			if ((vpg->oflags & VPO_BUSY) != 0) {
+				/*
+				 * Reference the page before unlocking and
+				 * sleeping so that the page daemon is less
+				 * likely to reclaim it.  
+			 	*/
+				vm_page_reference(vpg);
+				vm_page_sleep(vpg, "tmfsmw");
+				goto lookupvpg;
+			}
+			vm_page_busy(vpg);
+			vm_page_undirty(vpg);
+			VM_OBJECT_UNLOCK(vobj);
+			error = uiomove_fromphys(&vpg, offset, tlen, uio);
+		} else {
+			if (vpg->flags & PG_CACHED) {
+				mtx_lock(&vm_page_queue_free_mtx);
+				if (vpg->object == vobj)
+					vm_page_cache_free(vpg);
+				mtx_unlock(&vm_page_queue_free_mtx);
+			}
+			VM_OBJECT_UNLOCK(vobj);
+			vpg = NULL;
 		}
-		vm_page_busy(vpg);
-		vm_page_undirty(vpg);
-		VM_OBJECT_UNLOCK(vobj);
-		error = uiomove_fromphys(&vpg, offset, tlen, uio);
-	} else {
+	} else
 		VM_OBJECT_UNLOCK(vobj);
-		vpg = NULL;
-	}
 nocache:
 	VM_OBJECT_LOCK(tobj);
 	tpg = vm_page_grab(tobj, idx, VM_ALLOC_WIRED |


More information about the svn-src-user mailing list