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);
 
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "[email protected]"

Reply via email to