summaryrefslogtreecommitdiffstats
path: root/sys/vm/vm_object.c
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2015-06-06 20:37:40 +0000
committerjhb <jhb@FreeBSD.org>2015-06-06 20:37:40 +0000
commit51c06666a902e195ca88afc6b333748c1d7ad639 (patch)
treed1201d664486dbe0b7e77499d73ddb7f4ac6903a /sys/vm/vm_object.c
parentac9f7bc3c6a3d76b846574698062aab3d7b860f5 (diff)
downloadFreeBSD-src-51c06666a902e195ca88afc6b333748c1d7ad639.zip
FreeBSD-src-51c06666a902e195ca88afc6b333748c1d7ad639.tar.gz
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.
Diffstat (limited to 'sys/vm/vm_object.c')
-rw-r--r--sys/vm/vm_object.c32
1 files changed, 17 insertions, 15 deletions
diff --git a/sys/vm/vm_object.c b/sys/vm/vm_object.c
index 7c1d592..ab1562e 100644
--- a/sys/vm/vm_object.c
+++ b/sys/vm/vm_object.c
@@ -166,6 +166,8 @@ vm_object_zdtor(void *mem, int size, void *arg)
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, void *arg)
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 flags)
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 flags)
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_pindex_t size, vm_object_t object)
#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);
OpenPOWER on IntegriCloud