Index: sys/vm/vm_map.c =================================================================== --- sys/vm/vm_map.c +++ sys/vm/vm_map.c @@ -1011,6 +1011,13 @@ } static inline vm_size_t +vm_size_min(vm_size_t a, vm_size_t b) +{ + + return (a < b ? a : b); +} + +static inline vm_size_t vm_size_max(vm_size_t a, vm_size_t b) { @@ -2346,22 +2353,42 @@ static void _vm_map_clip_start(vm_map_t map, vm_map_entry_t entry, vm_offset_t start) { - vm_map_entry_t new_entry; + vm_map_entry_t llist, new_entry, prev_entry, y; + vm_size_t max_free; VM_MAP_ASSERT_LOCKED(map); KASSERT(entry->end > start && entry->start < start, ("_vm_map_clip_start: invalid clip of entry %p", entry)); - new_entry = vm_map_entry_clone(map, entry); - /* * Split off the front portion. Insert the new entry BEFORE this one, * so that this entry has the specified starting address. */ - new_entry->end = start; - entry->offset += (start - entry->start); - entry->start = start; - vm_map_entry_link(map, new_entry); + new_entry = vm_map_entry_clone(map, entry); + prev_entry = entry->left; + if (prev_entry->right->start < entry->start) { + llist = &map->header; + do + SPLAY_RIGHT_STEP(prev_entry, y, llist, entry, true); + while (prev_entry != NULL); + vm_map_splay_merge_pred(&map->header, entry, llist); + new_entry->left = prev_entry = llist; + max_free = entry->start - prev_entry->end; + prev_entry->right = new_entry; + } else { + entry->left = new_entry; + max_free = entry->start - prev_entry->end; + if (prev_entry->right == entry) { + max_free = vm_size_max(max_free, + vm_size_min(entry->max_free, prev_entry->max_free)); + prev_entry->right = new_entry; + } + } + new_entry->max_free = max_free; + new_entry->right = entry; + entry->offset += start - entry->start; + new_entry->end = entry->start = start; + map->nentries++; } /* @@ -2384,21 +2411,42 @@ static void _vm_map_clip_end(vm_map_t map, vm_map_entry_t entry, vm_offset_t end) { - vm_map_entry_t new_entry; + vm_map_entry_t next_entry, new_entry, rlist, y; + vm_size_t max_free; VM_MAP_ASSERT_LOCKED(map); KASSERT(entry->start < end && entry->end > end, ("_vm_map_clip_end: invalid clip of entry %p", entry)); - new_entry = vm_map_entry_clone(map, entry); - /* * Split off the back portion. Insert the new entry AFTER this one, * so that this entry has the specified ending address. */ + new_entry = vm_map_entry_clone(map, entry); + next_entry = entry->right; + if (next_entry->left->start > entry->start) { + rlist = &map->header; + do + SPLAY_LEFT_STEP(next_entry, y, entry, rlist, true); + while (next_entry != NULL); + vm_map_splay_merge_succ(&map->header, entry, rlist); + new_entry->right = next_entry = rlist; + max_free = next_entry->start - entry->end; + next_entry->left = new_entry; + } else { + entry->right = new_entry; + max_free = next_entry->start - entry->end; + if (next_entry->left == entry) { + max_free = vm_size_max(max_free, + vm_size_min(entry->max_free, next_entry->max_free)); + next_entry->left = new_entry; + } + } + new_entry->max_free = max_free; + new_entry->left = entry; + new_entry->offset += end - entry->start; new_entry->start = entry->end = end; - new_entry->offset += (end - entry->start); - vm_map_entry_link(map, new_entry); + map->nentries++; } /*