diff options
| author | Jeff Roberson <jeff@FreeBSD.org> | 2019-10-29 20:58:46 +0000 |
|---|---|---|
| committer | Jeff Roberson <jeff@FreeBSD.org> | 2019-10-29 20:58:46 +0000 |
| commit | 51df53213c2e297c8f36ff49550f9d17da0e6178 (patch) | |
| tree | 86bae6e1449d1e46be0c161ac9c4f61c9a940469 /sys/vm/vm_object.c | |
| parent | 4b3e066539b43e64c6da1cc8ec46c65be7b6790e (diff) | |
Notes
Diffstat (limited to 'sys/vm/vm_object.c')
| -rw-r--r-- | sys/vm/vm_object.c | 62 |
1 files changed, 31 insertions, 31 deletions
diff --git a/sys/vm/vm_object.c b/sys/vm/vm_object.c index 4023877d4565..7b01320371a0 100644 --- a/sys/vm/vm_object.c +++ b/sys/vm/vm_object.c @@ -224,8 +224,8 @@ vm_object_zinit(void *mem, int size, int flags) /* These are true for any object that has been freed */ object->type = OBJT_DEAD; - object->ref_count = 0; vm_radix_init(&object->rtree); + refcount_init(&object->ref_count, 0); refcount_init(&object->paging_in_progress, 0); refcount_init(&object->busy, 0); object->resident_page_count = 0; @@ -282,7 +282,7 @@ _vm_object_allocate(objtype_t type, vm_pindex_t size, vm_object_t object) object->size = size; object->domain.dr_policy = NULL; object->generation = 1; - object->ref_count = 1; + refcount_init(&object->ref_count, 1); object->memattr = VM_MEMATTR_DEFAULT; object->cred = NULL; object->charge = 0; @@ -444,9 +444,9 @@ vm_object_reference(vm_object_t object) { if (object == NULL) return; - VM_OBJECT_WLOCK(object); + VM_OBJECT_RLOCK(object); vm_object_reference_locked(object); - VM_OBJECT_WUNLOCK(object); + VM_OBJECT_RUNLOCK(object); } /* @@ -461,8 +461,8 @@ vm_object_reference_locked(vm_object_t object) { struct vnode *vp; - VM_OBJECT_ASSERT_WLOCKED(object); - object->ref_count++; + VM_OBJECT_ASSERT_LOCKED(object); + refcount_acquire(&object->ref_count); if (object->type == OBJT_VNODE) { vp = object->handle; vref(vp); @@ -477,24 +477,16 @@ vm_object_vndeallocate(vm_object_t object) { struct vnode *vp = (struct vnode *) object->handle; - VM_OBJECT_ASSERT_WLOCKED(object); KASSERT(object->type == OBJT_VNODE, ("vm_object_vndeallocate: not a vnode object")); KASSERT(vp != NULL, ("vm_object_vndeallocate: missing vp")); -#ifdef INVARIANTS - if (object->ref_count == 0) { - vn_printf(vp, "vm_object_vndeallocate "); - panic("vm_object_vndeallocate: bad object reference count"); - } -#endif - if (!umtx_shm_vnobj_persistent && object->ref_count == 1) + if (refcount_release(&object->ref_count) && + !umtx_shm_vnobj_persistent) umtx_shm_object_terminated(object); - object->ref_count--; - + VM_OBJECT_RUNLOCK(object); /* vrele may need the vnode lock. */ - VM_OBJECT_WUNLOCK(object); vrele(vp); } @@ -513,24 +505,32 @@ void vm_object_deallocate(vm_object_t object) { vm_object_t temp; + bool released; while (object != NULL) { - VM_OBJECT_WLOCK(object); + VM_OBJECT_RLOCK(object); if (object->type == OBJT_VNODE) { vm_object_vndeallocate(object); return; } - KASSERT(object->ref_count != 0, - ("vm_object_deallocate: object deallocated too many times: %d", object->type)); - /* * If the reference count goes to 0 we start calling - * vm_object_terminate() on the object chain. - * A ref count of 1 may be a special case depending on the - * shadow count being 0 or 1. + * vm_object_terminate() on the object chain. A ref count + * of 1 may be a special case depending on the shadow count + * being 0 or 1. These cases require a write lock on the + * object. */ - object->ref_count--; + released = refcount_release_if_gt(&object->ref_count, 2); + VM_OBJECT_RUNLOCK(object); + if (released) + return; + + VM_OBJECT_WLOCK(object); + KASSERT(object->ref_count != 0, + ("vm_object_deallocate: object deallocated too many times: %d", object->type)); + + refcount_release(&object->ref_count); if (object->ref_count > 1) { VM_OBJECT_WUNLOCK(object); return; @@ -558,7 +558,7 @@ vm_object_deallocate(vm_object_t object) /* * Avoid a potential deadlock. */ - object->ref_count++; + refcount_acquire(&object->ref_count); VM_OBJECT_WUNLOCK(object); /* * More likely than not the thread @@ -580,7 +580,7 @@ vm_object_deallocate(vm_object_t object) (robject->type == OBJT_DEFAULT || robject->type == OBJT_SWAP)) { - robject->ref_count++; + refcount_acquire(&robject->ref_count); retry: if (REFCOUNT_COUNT(robject->paging_in_progress) > 0) { VM_OBJECT_WUNLOCK(object); @@ -1223,15 +1223,15 @@ vm_object_shadow( * Don't create the new object if the old object isn't shared. */ if (source != NULL) { - VM_OBJECT_WLOCK(source); + VM_OBJECT_RLOCK(source); if (source->ref_count == 1 && source->handle == NULL && (source->type == OBJT_DEFAULT || source->type == OBJT_SWAP)) { - VM_OBJECT_WUNLOCK(source); + VM_OBJECT_RUNLOCK(source); return; } - VM_OBJECT_WUNLOCK(source); + VM_OBJECT_RUNLOCK(source); } /* @@ -1822,7 +1822,7 @@ vm_object_collapse(vm_object_t object) * Drop the reference count on backing_object. Since * its ref_count was at least 2, it will not vanish. */ - backing_object->ref_count--; + refcount_release(&backing_object->ref_count); VM_OBJECT_WUNLOCK(backing_object); counter_u64_add(object_bypasses, 1); } |
