Index: sys/vm/vm_meter.c =================================================================== --- sys/vm/vm_meter.c +++ sys/vm/vm_meter.c @@ -111,14 +111,7 @@ */ 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 @@ 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) { /* Index: sys/vm/vm_object.c =================================================================== --- sys/vm/vm_object.c +++ sys/vm/vm_object.c @@ -157,7 +157,6 @@ static int vm_object_zinit(void *mem, int size, int flags); -#ifdef INVARIANTS static void vm_object_zdtor(void *mem, int size, void *arg); static void @@ -166,6 +165,8 @@ 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,8 +188,8 @@ KASSERT(object->shadow_count == 0, ("object %p shadow_count = %d", object, object->shadow_count)); + object->type = OBJT_DEAD; } -#endif static int vm_object_zinit(void *mem, int size, int flags) @@ -199,6 +200,8 @@ 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 +209,10 @@ 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 +259,6 @@ #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,13 +674,6 @@ { /* - * 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) { @@ -1803,6 +1799,7 @@ KASSERT(backing_object->ref_count == 1, ( "backing_object %p was somehow re-referenced during collapse!", backing_object)); + backing_object->ref_count = 0; VM_OBJECT_WUNLOCK(backing_object); vm_object_destroy(backing_object);