Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 6 Jun 2015 20:37:41 +0000 (UTC)
From:      John Baldwin <jhb@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org
Subject:   svn commit: r284100 - in stable: 10/sys/vm 9/sys/vm
Message-ID:  <201506062037.t56KbfsP058560@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: jhb
Date: Sat Jun  6 20:37:40 2015
New Revision: 284100
URL: https://svnweb.freebsd.org/changeset/base/284100

Log:
  MFC 261811,282660,282706:
  Place VM objects on the object list when created and never remove them.
  
  261811:
  Fix function name in KASSERT().
  
  282660:
  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.)
  
  282706:
  Satisfy vm_object uma zone destructor requirements after r282660 when
  vnode object creation raced.

Modified:
  stable/10/sys/vm/default_pager.c
  stable/10/sys/vm/device_pager.c
  stable/10/sys/vm/phys_pager.c
  stable/10/sys/vm/sg_pager.c
  stable/10/sys/vm/swap_pager.c
  stable/10/sys/vm/vm_meter.c
  stable/10/sys/vm/vm_object.c
  stable/10/sys/vm/vnode_pager.c
Directory Properties:
  stable/10/   (props changed)

Changes in other areas also in this revision:
Modified:
  stable/9/sys/vm/default_pager.c
  stable/9/sys/vm/device_pager.c
  stable/9/sys/vm/phys_pager.c
  stable/9/sys/vm/sg_pager.c
  stable/9/sys/vm/swap_pager.c
  stable/9/sys/vm/vm_meter.c
  stable/9/sys/vm/vm_object.c
  stable/9/sys/vm/vnode_pager.c
Directory Properties:
  stable/9/sys/   (props changed)

Modified: stable/10/sys/vm/default_pager.c
==============================================================================
--- stable/10/sys/vm/default_pager.c	Sat Jun  6 20:14:58 2015	(r284099)
+++ stable/10/sys/vm/default_pager.c	Sat Jun  6 20:37:40 2015	(r284100)
@@ -113,6 +113,7 @@ default_pager_dealloc(object)
 	/*
 	 * OBJT_DEFAULT objects have no special resources allocated to them.
 	 */
+	object->type = OBJT_DEAD;
 }
 
 /*

Modified: stable/10/sys/vm/device_pager.c
==============================================================================
--- stable/10/sys/vm/device_pager.c	Sat Jun  6 20:14:58 2015	(r284099)
+++ stable/10/sys/vm/device_pager.c	Sat Jun  6 20:37:40 2015	(r284100)
@@ -252,6 +252,8 @@ dev_pager_dealloc(object)
 		    != NULL)
 			dev_pager_free_page(object, m);
 	}
+	object->handle = NULL;
+	object->type = OBJT_DEAD;
 }
 
 static int

Modified: stable/10/sys/vm/phys_pager.c
==============================================================================
--- stable/10/sys/vm/phys_pager.c	Sat Jun  6 20:14:58 2015	(r284099)
+++ stable/10/sys/vm/phys_pager.c	Sat Jun  6 20:37:40 2015	(r284100)
@@ -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: stable/10/sys/vm/sg_pager.c
==============================================================================
--- stable/10/sys/vm/sg_pager.c	Sat Jun  6 20:14:58 2015	(r284099)
+++ stable/10/sys/vm/sg_pager.c	Sat Jun  6 20:37:40 2015	(r284100)
@@ -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: stable/10/sys/vm/swap_pager.c
==============================================================================
--- stable/10/sys/vm/swap_pager.c	Sat Jun  6 20:14:58 2015	(r284099)
+++ stable/10/sys/vm/swap_pager.c	Sat Jun  6 20:37:40 2015	(r284100)
@@ -693,6 +693,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: stable/10/sys/vm/vm_meter.c
==============================================================================
--- stable/10/sys/vm/vm_meter.c	Sat Jun  6 20:14:58 2015	(r284099)
+++ stable/10/sys/vm/vm_meter.c	Sat Jun  6 20:37:40 2015	(r284100)
@@ -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: stable/10/sys/vm/vm_object.c
==============================================================================
--- stable/10/sys/vm/vm_object.c	Sat Jun  6 20:14:58 2015	(r284099)
+++ stable/10/sys/vm/vm_object.c	Sat Jun  6 20:37:40 2015	(r284100)
@@ -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
 
@@ -200,6 +205,8 @@ vm_object_zinit(void *mem, int size, int
 	rw_init_flags(&object->lock, "vm object", RW_DUPOK);
 
 	/* 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;
@@ -207,6 +214,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);
 }
 
@@ -253,10 +264,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);
 }
 
 /*
@@ -672,20 +679,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,
-		    ("vm_object_terminate: non-swap obj %p has cred",
-		     object));
 		swap_release_by_cred(object->charge, object->cred);
 		object->charge = 0;
 		crfree(object->cred);
@@ -790,6 +786,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.
 	 */
@@ -1805,6 +1805,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);
 

Modified: stable/10/sys/vm/vnode_pager.c
==============================================================================
--- stable/10/sys/vm/vnode_pager.c	Sat Jun  6 20:14:58 2015	(r284099)
+++ stable/10/sys/vm/vnode_pager.c	Sat Jun  6 20:37:40 2015	(r284100)
@@ -227,6 +227,12 @@ retry:
 			 * Object has been created while we were sleeping
 			 */
 			VI_UNLOCK(vp);
+			VM_OBJECT_WLOCK(object);
+			KASSERT(object->ref_count == 1,
+			    ("leaked ref %p %d", object, object->ref_count));
+			object->type = OBJT_DEAD;
+			object->ref_count = 0;
+			VM_OBJECT_WUNLOCK(object);
 			vm_object_destroy(object);
 			goto retry;
 		}



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201506062037.t56KbfsP058560>