aboutsummaryrefslogtreecommitdiff
path: root/sys/vm/vm_object.c
diff options
context:
space:
mode:
authorJeff Roberson <jeff@FreeBSD.org>2019-10-29 20:58:46 +0000
committerJeff Roberson <jeff@FreeBSD.org>2019-10-29 20:58:46 +0000
commit51df53213c2e297c8f36ff49550f9d17da0e6178 (patch)
tree86bae6e1449d1e46be0c161ac9c4f61c9a940469 /sys/vm/vm_object.c
parent4b3e066539b43e64c6da1cc8ec46c65be7b6790e (diff)
Notes
Diffstat (limited to 'sys/vm/vm_object.c')
-rw-r--r--sys/vm/vm_object.c62
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);
}