svn commit: r282660 - head/sys/vm

John Baldwin jhb at FreeBSD.org
Fri May 8 19:43:40 UTC 2015


Author: jhb
Date: Fri May  8 19:43:37 2015
New Revision: 282660
URL: https://svnweb.freebsd.org/changeset/base/282660

Log:
  Place VM objects on the object list when created and never remove them.
  This is ok since objects come from a NOFREE zone and allows objects to
  be locked while traversing the object list without triggering a LOR.
  
  Ensure that objects on the list are marked DEAD while free or stillborn,
  and that they have a refcount of zero.  This required updating most of
  the pagers to explicitly mark an object as dead when deallocating it.
  (Only the vnode pager did this previously.)
  
  Differential Revision:	https://reviews.freebsd.org/D2423
  Reviewed by:	alc, kib (earlier version)
  MFC after:	2 weeks
  Sponsored by:	Norse Corp, Inc.

Modified:
  head/sys/vm/default_pager.c
  head/sys/vm/device_pager.c
  head/sys/vm/phys_pager.c
  head/sys/vm/sg_pager.c
  head/sys/vm/swap_pager.c
  head/sys/vm/vm_meter.c
  head/sys/vm/vm_object.c

Modified: head/sys/vm/default_pager.c
==============================================================================
--- head/sys/vm/default_pager.c	Fri May  8 19:41:04 2015	(r282659)
+++ head/sys/vm/default_pager.c	Fri May  8 19:43:37 2015	(r282660)
@@ -113,6 +113,7 @@ default_pager_dealloc(object)
 	/*
 	 * OBJT_DEFAULT objects have no special resources allocated to them.
 	 */
+	object->type = OBJT_DEAD;
 }
 
 /*

Modified: head/sys/vm/device_pager.c
==============================================================================
--- head/sys/vm/device_pager.c	Fri May  8 19:41:04 2015	(r282659)
+++ head/sys/vm/device_pager.c	Fri May  8 19:43:37 2015	(r282660)
@@ -254,6 +254,8 @@ dev_pager_dealloc(object)
 		    != NULL)
 			dev_pager_free_page(object, m);
 	}
+	object->handle = NULL;
+	object->type = OBJT_DEAD;
 }
 
 static int

Modified: head/sys/vm/phys_pager.c
==============================================================================
--- head/sys/vm/phys_pager.c	Fri May  8 19:41:04 2015	(r282659)
+++ head/sys/vm/phys_pager.c	Fri May  8 19:43:37 2015	(r282660)
@@ -131,6 +131,8 @@ phys_pager_dealloc(vm_object_t object)
 		mtx_unlock(&phys_pager_mtx);
 		VM_OBJECT_WLOCK(object);
 	}
+	object->handle = NULL;
+	object->type = OBJT_DEAD;
 }
 
 /*

Modified: head/sys/vm/sg_pager.c
==============================================================================
--- head/sys/vm/sg_pager.c	Fri May  8 19:41:04 2015	(r282659)
+++ head/sys/vm/sg_pager.c	Fri May  8 19:43:37 2015	(r282660)
@@ -130,6 +130,8 @@ sg_pager_dealloc(vm_object_t object)
 	
 	sg = object->handle;
 	sglist_free(sg);
+	object->handle = NULL;
+	object->type = OBJT_DEAD;
 }
 
 static int

Modified: head/sys/vm/swap_pager.c
==============================================================================
--- head/sys/vm/swap_pager.c	Fri May  8 19:41:04 2015	(r282659)
+++ head/sys/vm/swap_pager.c	Fri May  8 19:43:37 2015	(r282660)
@@ -697,6 +697,8 @@ swap_pager_dealloc(vm_object_t object)
 	 * if paging is still in progress on some objects.
 	 */
 	swp_pager_meta_free_all(object);
+	object->handle = NULL;
+	object->type = OBJT_DEAD;
 }
 
 /************************************************************************

Modified: head/sys/vm/vm_meter.c
==============================================================================
--- head/sys/vm/vm_meter.c	Fri May  8 19:41:04 2015	(r282659)
+++ head/sys/vm/vm_meter.c	Fri May  8 19:43:37 2015	(r282660)
@@ -111,14 +111,7 @@ vmtotal(SYSCTL_HANDLER_ARGS)
 	 */
 	mtx_lock(&vm_object_list_mtx);
 	TAILQ_FOREACH(object, &vm_object_list, object_list) {
-		if (!VM_OBJECT_TRYWLOCK(object)) {
-			/*
-			 * Avoid a lock-order reversal.  Consequently,
-			 * the reported number of active pages may be
-			 * greater than the actual number.
-			 */
-			continue;
-		}
+		VM_OBJECT_WLOCK(object);
 		vm_object_clear_flag(object, OBJ_ACTIVE);
 		VM_OBJECT_WUNLOCK(object);
 	}
@@ -196,10 +189,9 @@ vmtotal(SYSCTL_HANDLER_ARGS)
 	mtx_lock(&vm_object_list_mtx);
 	TAILQ_FOREACH(object, &vm_object_list, object_list) {
 		/*
-		 * Perform unsynchronized reads on the object to avoid
-		 * a lock-order reversal.  In this case, the lack of
-		 * synchronization should not impair the accuracy of
-		 * the reported statistics. 
+		 * Perform unsynchronized reads on the object.  In
+		 * this case, the lack of synchronization should not
+		 * impair the accuracy of the reported statistics.
 		 */
 		if ((object->flags & OBJ_FICTITIOUS) != 0) {
 			/*

Modified: head/sys/vm/vm_object.c
==============================================================================
--- head/sys/vm/vm_object.c	Fri May  8 19:41:04 2015	(r282659)
+++ head/sys/vm/vm_object.c	Fri May  8 19:43:37 2015	(r282660)
@@ -166,6 +166,8 @@ vm_object_zdtor(void *mem, int size, voi
 	vm_object_t object;
 
 	object = (vm_object_t)mem;
+	KASSERT(object->ref_count == 0,
+	    ("object %p ref_count = %d", object, object->ref_count));
 	KASSERT(TAILQ_EMPTY(&object->memq),
 	    ("object %p has resident pages in its memq", object));
 	KASSERT(vm_radix_is_empty(&object->rtree),
@@ -187,6 +189,9 @@ vm_object_zdtor(void *mem, int size, voi
 	KASSERT(object->shadow_count == 0,
 	    ("object %p shadow_count = %d",
 	    object, object->shadow_count));
+	KASSERT(object->type == OBJT_DEAD,
+	    ("object %p has non-dead type %d",
+	    object, object->type));
 }
 #endif
 
@@ -199,6 +204,8 @@ vm_object_zinit(void *mem, int size, int
 	rw_init_flags(&object->lock, "vm object", RW_DUPOK | RW_NEW);
 
 	/* These are true for any object that has been freed */
+	object->type = OBJT_DEAD;
+	object->ref_count = 0;
 	object->rtree.rt_root = 0;
 	object->rtree.rt_flags = 0;
 	object->paging_in_progress = 0;
@@ -206,6 +213,10 @@ vm_object_zinit(void *mem, int size, int
 	object->shadow_count = 0;
 	object->cache.rt_root = 0;
 	object->cache.rt_flags = 0;
+
+	mtx_lock(&vm_object_list_mtx);
+	TAILQ_INSERT_TAIL(&vm_object_list, object, object_list);
+	mtx_unlock(&vm_object_list_mtx);
 	return (0);
 }
 
@@ -252,10 +263,6 @@ _vm_object_allocate(objtype_t type, vm_p
 #if VM_NRESERVLEVEL > 0
 	LIST_INIT(&object->rvq);
 #endif
-
-	mtx_lock(&vm_object_list_mtx);
-	TAILQ_INSERT_TAIL(&vm_object_list, object, object_list);
-	mtx_unlock(&vm_object_list_mtx);
 }
 
 /*
@@ -671,19 +678,9 @@ vm_object_destroy(vm_object_t object)
 {
 
 	/*
-	 * Remove the object from the global object list.
-	 */
-	mtx_lock(&vm_object_list_mtx);
-	TAILQ_REMOVE(&vm_object_list, object, object_list);
-	mtx_unlock(&vm_object_list_mtx);
-
-	/*
 	 * Release the allocation charge.
 	 */
 	if (object->cred != NULL) {
-		KASSERT(object->type == OBJT_DEFAULT ||
-		    object->type == OBJT_SWAP,
-		    ("%s: non-swap obj %p has cred", __func__, object));
 		swap_release_by_cred(object->charge, object->cred);
 		object->charge = 0;
 		crfree(object->cred);
@@ -788,6 +785,10 @@ vm_object_terminate(vm_object_t object)
 	if (__predict_false(!vm_object_cache_is_empty(object)))
 		vm_page_cache_free(object, 0, 0);
 
+	KASSERT(object->cred == NULL || object->type == OBJT_DEFAULT ||
+	    object->type == OBJT_SWAP,
+	    ("%s: non-swap obj %p has cred", __func__, object));
+
 	/*
 	 * Let the pager know object is dead.
 	 */
@@ -1803,6 +1804,8 @@ vm_object_collapse(vm_object_t object)
 			KASSERT(backing_object->ref_count == 1, (
 "backing_object %p was somehow re-referenced during collapse!",
 			    backing_object));
+			backing_object->type = OBJT_DEAD;
+			backing_object->ref_count = 0;
 			VM_OBJECT_WUNLOCK(backing_object);
 			vm_object_destroy(backing_object);
 


More information about the svn-src-head mailing list