summaryrefslogtreecommitdiff
path: root/vm
diff options
context:
space:
mode:
authorSergey Bugaev <bugaevc@gmail.com>2023-06-26 14:26:53 +0300
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2023-07-03 02:14:43 +0200
commitd57189313d359bfa4033d24b3c4248b539826763 (patch)
tree6c059a0407e5d932f382dfaeebdbd7443066e6c8 /vm
parentee65849bec5da261be90f565bee096abb4117bdd (diff)
vm: Allow coalescing entries forward
When entering an object into a map, try to extend the next entry backward, in addition to the previously existing attempt to extend the previous entry forward. Message-Id: <20230626112656.435622-5-bugaevc@gmail.com>
Diffstat (limited to 'vm')
-rw-r--r--vm/vm_map.c39
1 files changed, 35 insertions, 4 deletions
diff --git a/vm/vm_map.c b/vm/vm_map.c
index f701a4cf..a708b7eb 100644
--- a/vm/vm_map.c
+++ b/vm/vm_map.c
@@ -967,6 +967,7 @@ kern_return_t vm_map_enter(
vm_inherit_t inheritance)
{
vm_map_entry_t entry;
+ vm_map_entry_t next_entry;
vm_offset_t start;
vm_offset_t end;
kern_return_t result = KERN_SUCCESS;
@@ -987,6 +988,7 @@ kern_return_t vm_map_enter(
end = start + size;
*address = start;
+ next_entry = entry->vme_next;
} else {
vm_map_entry_t temp_entry;
@@ -1021,14 +1023,15 @@ kern_return_t vm_map_enter(
RETURN(KERN_NO_SPACE);
entry = temp_entry;
+ next_entry = entry->vme_next;
/*
* ... the next region doesn't overlap the
* end point.
*/
- if ((entry->vme_next != vm_map_to_entry(map)) &&
- (entry->vme_next->vme_start < end))
+ if ((next_entry != vm_map_to_entry(map)) &&
+ (next_entry->vme_start < end))
RETURN(KERN_NO_SPACE);
}
@@ -1044,8 +1047,7 @@ kern_return_t vm_map_enter(
/*
* See whether we can avoid creating a new entry (and object) by
- * extending one of our neighbors. [So far, we only attempt to
- * extend from below.]
+ * extending one of our neighbors.
*/
if ((entry != vm_map_to_entry(map)) &&
@@ -1076,6 +1078,35 @@ kern_return_t vm_map_enter(
RETURN(KERN_SUCCESS);
}
}
+ if ((next_entry != vm_map_to_entry(map)) &&
+ (next_entry->vme_start == end) &&
+ (!next_entry->is_shared) &&
+ (!next_entry->is_sub_map) &&
+ (next_entry->inheritance == inheritance) &&
+ (next_entry->protection == cur_protection) &&
+ (next_entry->max_protection == max_protection) &&
+ (next_entry->wired_count == 0) &&
+ (next_entry->projected_on == 0)) {
+ if (vm_object_coalesce(object,
+ next_entry->object.vm_object,
+ offset,
+ next_entry->offset,
+ size,
+ (vm_size_t)(next_entry->vme_end - next_entry->vme_start))) {
+
+ /*
+ * Coalesced the two objects - can extend
+ * the next map entry to include the
+ * new range.
+ */
+ map->size += size;
+ next_entry->vme_start = start;
+ next_entry->offset -= size;
+ vm_map_gap_update(&map->hdr, entry);
+ vm_object_deallocate(object);
+ RETURN(KERN_SUCCESS);
+ }
+ }
/*
* Create a new entry