diff options
author | jhb <jhb@FreeBSD.org> | 2015-06-06 20:37:40 +0000 |
---|---|---|
committer | jhb <jhb@FreeBSD.org> | 2015-06-06 20:37:40 +0000 |
commit | 51c06666a902e195ca88afc6b333748c1d7ad639 (patch) | |
tree | d1201d664486dbe0b7e77499d73ddb7f4ac6903a /sys/vm/vm_object.c | |
parent | ac9f7bc3c6a3d76b846574698062aab3d7b860f5 (diff) | |
download | FreeBSD-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.c | 32 |
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); |