Fix a perf regression from r355122. We can use a shared lock to drop the
last ref on vnodes. Reviewed by: kib, markj Differential Revision: https://reviews.freebsd.org/D22565
This commit is contained in:
parent
846419f898
commit
26c4e9831b
@ -520,15 +520,22 @@ static void
|
|||||||
vm_object_vndeallocate(vm_object_t object)
|
vm_object_vndeallocate(vm_object_t object)
|
||||||
{
|
{
|
||||||
struct vnode *vp = (struct vnode *) object->handle;
|
struct vnode *vp = (struct vnode *) object->handle;
|
||||||
|
bool last;
|
||||||
|
|
||||||
KASSERT(object->type == OBJT_VNODE,
|
KASSERT(object->type == OBJT_VNODE,
|
||||||
("vm_object_vndeallocate: not a vnode object"));
|
("vm_object_vndeallocate: not a vnode object"));
|
||||||
KASSERT(vp != NULL, ("vm_object_vndeallocate: missing vp"));
|
KASSERT(vp != NULL, ("vm_object_vndeallocate: missing vp"));
|
||||||
|
|
||||||
|
/* Object lock to protect handle lookup. */
|
||||||
|
last = refcount_release(&object->ref_count);
|
||||||
|
VM_OBJECT_RUNLOCK(object);
|
||||||
|
|
||||||
|
if (!last)
|
||||||
|
return;
|
||||||
|
|
||||||
if (!umtx_shm_vnobj_persistent)
|
if (!umtx_shm_vnobj_persistent)
|
||||||
umtx_shm_object_terminated(object);
|
umtx_shm_object_terminated(object);
|
||||||
|
|
||||||
VM_OBJECT_WUNLOCK(object);
|
|
||||||
/* vrele may need the vnode lock. */
|
/* vrele may need the vnode lock. */
|
||||||
vrele(vp);
|
vrele(vp);
|
||||||
}
|
}
|
||||||
@ -548,7 +555,7 @@ void
|
|||||||
vm_object_deallocate(vm_object_t object)
|
vm_object_deallocate(vm_object_t object)
|
||||||
{
|
{
|
||||||
vm_object_t robject, temp;
|
vm_object_t robject, temp;
|
||||||
bool last, released;
|
bool released;
|
||||||
|
|
||||||
while (object != NULL) {
|
while (object != NULL) {
|
||||||
/*
|
/*
|
||||||
@ -565,18 +572,22 @@ vm_object_deallocate(vm_object_t object)
|
|||||||
if (released)
|
if (released)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
VM_OBJECT_WLOCK(object);
|
|
||||||
KASSERT(object->ref_count != 0,
|
|
||||||
("vm_object_deallocate: object deallocated too many times: %d", object->type));
|
|
||||||
|
|
||||||
last = refcount_release(&object->ref_count);
|
|
||||||
if (object->type == OBJT_VNODE) {
|
if (object->type == OBJT_VNODE) {
|
||||||
if (last)
|
VM_OBJECT_RLOCK(object);
|
||||||
|
if (object->type == OBJT_VNODE) {
|
||||||
vm_object_vndeallocate(object);
|
vm_object_vndeallocate(object);
|
||||||
else
|
return;
|
||||||
VM_OBJECT_WUNLOCK(object);
|
}
|
||||||
return;
|
VM_OBJECT_RUNLOCK(object);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VM_OBJECT_WLOCK(object);
|
||||||
|
KASSERT(object->ref_count > 0,
|
||||||
|
("vm_object_deallocate: object deallocated too many times: %d",
|
||||||
|
object->type));
|
||||||
|
|
||||||
|
if (refcount_release(&object->ref_count))
|
||||||
|
goto doterm;
|
||||||
if (object->ref_count > 1) {
|
if (object->ref_count > 1) {
|
||||||
VM_OBJECT_WUNLOCK(object);
|
VM_OBJECT_WUNLOCK(object);
|
||||||
return;
|
return;
|
||||||
|
Loading…
Reference in New Issue
Block a user