diff options
author | alc <alc@FreeBSD.org> | 2003-06-04 21:07:42 +0000 |
---|---|---|
committer | alc <alc@FreeBSD.org> | 2003-06-04 21:07:42 +0000 |
commit | 3be7bee315fcc67ca8e66e9f825136ec90a1e279 (patch) | |
tree | 334988a05bbb072a2672daffe5c3a99c6ae7d699 /sys | |
parent | 25569ea7316a1e368cc2dc4f53090ba1a8926fe6 (diff) | |
download | FreeBSD-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.c | 14 |
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; |