diff options
author | alc <alc@FreeBSD.org> | 2003-09-18 02:26:03 +0000 |
---|---|---|
committer | alc <alc@FreeBSD.org> | 2003-09-18 02:26:03 +0000 |
commit | 1644dd5fce2192d54736b9824e5a6cd6ec9ef0fa (patch) | |
tree | 1410c2003b81bbc19af1d323168d690a78204dd8 | |
parent | 8e2cce2cfe9c258058e4f193aa6cb50e389a0c1a (diff) | |
download | FreeBSD-src-1644dd5fce2192d54736b9824e5a6cd6ec9ef0fa.zip FreeBSD-src-1644dd5fce2192d54736b9824e5a6cd6ec9ef0fa.tar.gz |
Add vm object locking to vnode_pager_lock(). (This triggers the movement
of a VM_OBJECT_LOCK() in vm_fault().)
-rw-r--r-- | sys/vm/vm_fault.c | 2 | ||||
-rw-r--r-- | sys/vm/vnode_pager.c | 46 |
2 files changed, 33 insertions, 15 deletions
diff --git a/sys/vm/vm_fault.c b/sys/vm/vm_fault.c index 2f87cb7..855ff71 100644 --- a/sys/vm/vm_fault.c +++ b/sys/vm/vm_fault.c @@ -282,8 +282,8 @@ RetryFault:; * XXX vnode_pager_lock() can block without releasing the map lock. */ vm_object_reference(fs.first_object); - fs.vp = vnode_pager_lock(fs.first_object); VM_OBJECT_LOCK(fs.first_object); + fs.vp = vnode_pager_lock(fs.first_object); vm_object_pip_add(fs.first_object, 1); fs.lookup_still_valid = TRUE; diff --git a/sys/vm/vnode_pager.c b/sys/vm/vnode_pager.c index 2e60cef..e6badfe 100644 --- a/sys/vm/vnode_pager.c +++ b/sys/vm/vnode_pager.c @@ -1079,28 +1079,46 @@ vnode_pager_generic_putpages(vp, m, bytecount, flags, rtvals) } struct vnode * -vnode_pager_lock(object) - vm_object_t object; +vnode_pager_lock(vm_object_t first_object) { - struct thread *td = curthread; /* XXX */ - - GIANT_REQUIRED; - - for (; object != NULL; object = object->backing_object) { - if (object->type != OBJT_VNODE) + struct vnode *vp; + vm_object_t backing_object, object; + + VM_OBJECT_LOCK_ASSERT(first_object, MA_OWNED); + for (object = first_object; object != NULL; object = backing_object) { + if (object->type != OBJT_VNODE) { + if ((backing_object = object->backing_object) != NULL) + VM_OBJECT_LOCK(backing_object); + if (object != first_object) + VM_OBJECT_UNLOCK(object); continue; + } + retry: if (object->flags & OBJ_DEAD) { + if (object != first_object) + VM_OBJECT_UNLOCK(object); return NULL; } - - /* XXX; If object->handle can change, we need to cache it. */ - while (vget(object->handle, - LK_NOPAUSE | LK_SHARED | LK_RETRY | LK_CANRECURSE, td)){ - if ((object->flags & OBJ_DEAD) || (object->type != OBJT_VNODE)) + vp = object->handle; + VI_LOCK(vp); + VM_OBJECT_UNLOCK(object); + if (first_object != object) + VM_OBJECT_UNLOCK(first_object); + if (vget(vp, LK_CANRECURSE | LK_INTERLOCK | LK_NOPAUSE | + LK_RETRY | LK_SHARED, curthread)) { + VM_OBJECT_LOCK(first_object); + if (object != first_object) + VM_OBJECT_LOCK(object); + if (object->type != OBJT_VNODE) { + if (object != first_object) + VM_OBJECT_UNLOCK(object); return NULL; + } printf("vnode_pager_lock: retrying\n"); + goto retry; } - return object->handle; + VM_OBJECT_LOCK(first_object); + return (vp); } return NULL; } |