summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authoralc <alc@FreeBSD.org>2003-06-04 21:07:42 +0000
committeralc <alc@FreeBSD.org>2003-06-04 21:07:42 +0000
commit3be7bee315fcc67ca8e66e9f825136ec90a1e279 (patch)
tree334988a05bbb072a2672daffe5c3a99c6ae7d699 /sys
parent25569ea7316a1e368cc2dc4f53090ba1a8926fe6 (diff)
downloadFreeBSD-src-3be7bee315fcc67ca8e66e9f825136ec90a1e279.zip
FreeBSD-src-3be7bee315fcc67ca8e66e9f825136ec90a1e279.tar.gz
- Add further vm object locking to vm_object_deallocate(), specifically,
for accessing a vm object's shadows.
Diffstat (limited to 'sys')
-rw-r--r--sys/vm/vm_object.c14
1 files changed, 12 insertions, 2 deletions
diff --git a/sys/vm/vm_object.c b/sys/vm/vm_object.c
index 8b098ba..6883893 100644
--- a/sys/vm/vm_object.c
+++ b/sys/vm/vm_object.c
@@ -476,6 +476,14 @@ vm_object_deallocate(vm_object_t object)
("vm_object_deallocate: ref_count: %d, shadow_count: %d",
object->ref_count,
object->shadow_count));
+ if (!VM_OBJECT_TRYLOCK(robject)) {
+ /*
+ * Avoid a potential deadlock.
+ */
+ object->ref_count++;
+ VM_OBJECT_UNLOCK(object);
+ continue;
+ }
if ((robject->handle == NULL) &&
(robject->type == OBJT_DEFAULT ||
robject->type == OBJT_SWAP)) {
@@ -487,22 +495,24 @@ vm_object_deallocate(vm_object_t object)
object->paging_in_progress
) {
/* XXX */ VM_OBJECT_UNLOCK(object);
+ /* XXX */ VM_OBJECT_UNLOCK(robject);
vm_object_pip_sleep(robject, "objde1");
vm_object_pip_sleep(object, "objde2");
+ /* XXX */ VM_OBJECT_LOCK(robject);
/* XXX */ VM_OBJECT_LOCK(object);
}
VM_OBJECT_UNLOCK(object);
if (robject->ref_count == 1) {
- /* XXX */ VM_OBJECT_LOCK(robject);
robject->ref_count--;
object = robject;
goto doterm;
}
-
object = robject;
+ /* XXX */ VM_OBJECT_UNLOCK(object);
vm_object_collapse(object);
continue;
}
+ VM_OBJECT_UNLOCK(robject);
}
VM_OBJECT_UNLOCK(object);
goto done;
OpenPOWER on IntegriCloud