diff options
Diffstat (limited to 'vm/vm_map.c')
-rw-r--r-- | vm/vm_map.c | 55 |
1 files changed, 39 insertions, 16 deletions
diff --git a/vm/vm_map.c b/vm/vm_map.c index ae3ce21..9098dfd 100644 --- a/vm/vm_map.c +++ b/vm/vm_map.c @@ -1182,16 +1182,20 @@ kern_return_t vm_map_submap( if ((entry->vme_start == start) && (entry->vme_end == end) && (!entry->is_sub_map) && - ((object = entry->object.vm_object) == vm_submap_object) && - (object->resident_page_count == 0) && - (object->copy == VM_OBJECT_NULL) && - (object->shadow == VM_OBJECT_NULL) && - (!object->pager_created)) { - entry->object.vm_object = VM_OBJECT_NULL; - vm_object_deallocate(object); - entry->is_sub_map = TRUE; - vm_map_reference(entry->object.sub_map = submap); - result = KERN_SUCCESS; + ((object = entry->object.vm_object) == vm_submap_object)) { + vm_object_lock(object); + if ((object->resident_page_count == 0) && + (object->copy == VM_OBJECT_NULL) && + (object->shadow == VM_OBJECT_NULL) && + (!object->pager_created)) { + vm_object_unlock(object); + entry->object.vm_object = VM_OBJECT_NULL; + vm_object_deallocate(object); + entry->is_sub_map = TRUE; + vm_map_reference(entry->object.sub_map = submap); + result = KERN_SUCCESS; + } else + vm_object_unlock(object); } vm_map_unlock(map); @@ -2122,6 +2126,7 @@ start_pass_1: for (entry = tmp_entry;;) { vm_size_t sub_size = (entry->vme_end - entry->vme_start); vm_map_entry_t next = entry->vme_next; + vm_object_t object; if ( ! (entry->protection & VM_PROT_WRITE)) { vm_map_unlock(dst_map); @@ -2157,10 +2162,13 @@ start_pass_1: /* * Check for permanent objects in the destination. */ - - if ((entry->object.vm_object != VM_OBJECT_NULL) && - !entry->object.vm_object->temporary) - contains_permanent_objects = TRUE; + object = entry->object.vm_object; + if ((object != VM_OBJECT_NULL) + && ! contains_permanent_objects) { + vm_object_lock(object); + contains_permanent_objects = object->temporary; + vm_object_unlock(object); + } size -= sub_size; entry = next; @@ -2220,6 +2228,7 @@ start_pass_1: vm_map_entry_t copy_entry = vm_map_copy_first_entry(copy); vm_size_t copy_size = (copy_entry->vme_end - copy_entry->vme_start); vm_object_t object; + int temporary; entry = tmp_entry; size = (entry->vme_end - entry->vme_start); @@ -2275,8 +2284,15 @@ start_pass_1: */ object = entry->object.vm_object; + temporary = 0; + if (object != VM_OBJECT_NULL) { + vm_object_lock(object); + temporary = object->temporary; + vm_object_unlock(object); + } + if (!entry->is_shared && - ((object == VM_OBJECT_NULL) || object->temporary)) { + ((object == VM_OBJECT_NULL) || temporary)) { vm_object_t old_object = entry->object.vm_object; vm_offset_t old_offset = entry->offset; @@ -3219,11 +3235,15 @@ kern_return_t vm_map_copyin( /* * Attempt non-blocking copy-on-write optimizations. */ - + if (src_object) + vm_object_lock(src_object); if (src_destroy && (src_object == VM_OBJECT_NULL || (src_object->temporary && !src_object->use_shared_copy))) { + if (src_object) + vm_object_unlock(src_object); + /* * If we are destroying the source, and the object * is temporary, and not shared writable, @@ -3243,6 +3263,9 @@ kern_return_t vm_map_copyin( goto CopySuccessful; } + if (src_object) + vm_object_unlock(src_object); + if (!was_wired && vm_object_copy_temporary( &new_entry->object.vm_object, |