summaryrefslogtreecommitdiff
path: root/vm/vm_map.c
diff options
context:
space:
mode:
Diffstat (limited to 'vm/vm_map.c')
-rw-r--r--vm/vm_map.c55
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,