Index: head/sys/security/mac/mac_process.c =================================================================== --- head/sys/security/mac/mac_process.c +++ head/sys/security/mac/mac_process.c @@ -363,7 +363,7 @@ } pmap_protect(map->pmap, vme->start, vme->end, vme->protection & ~revokeperms); - vm_map_simplify_entry(map, vme); + vm_map_try_merge_entries(map, vme->prev, vme); } } vm_map_unlock(map); Index: head/sys/vm/vm_map.h =================================================================== --- head/sys/vm/vm_map.h +++ head/sys/vm/vm_map.h @@ -418,7 +418,8 @@ boolean_t vm_map_lookup_entry (vm_map_t, vm_offset_t, vm_map_entry_t *); int vm_map_protect (vm_map_t, vm_offset_t, vm_offset_t, vm_prot_t, boolean_t); int vm_map_remove (vm_map_t, vm_offset_t, vm_offset_t); -void vm_map_simplify_entry(vm_map_t map, vm_map_entry_t entry); +void vm_map_try_merge_entries(vm_map_t map, vm_map_entry_t prev, + vm_map_entry_t entry); void vm_map_startup (void); int vm_map_submap (vm_map_t, vm_offset_t, vm_offset_t, vm_map_t); int vm_map_sync(vm_map_t, vm_offset_t, vm_offset_t, boolean_t, boolean_t); Index: head/sys/vm/vm_map.c =================================================================== --- head/sys/vm/vm_map.c +++ head/sys/vm/vm_map.c @@ -1554,7 +1554,7 @@ map->size += end - prev_entry->end; vm_map_entry_resize(map, prev_entry, end - prev_entry->end); - vm_map_simplify_entry(map, prev_entry); + vm_map_try_merge_entries(map, prev_entry, prev_entry->next); return (KERN_SUCCESS); } @@ -1614,7 +1614,8 @@ * with the previous entry when object is NULL. Here, we handle the * other cases, which are less common. */ - vm_map_simplify_entry(map, new_entry); + vm_map_try_merge_entries(map, prev_entry, new_entry); + vm_map_try_merge_entries(map, new_entry, new_entry->next); if ((cow & (MAP_PREFAULT | MAP_PREFAULT_PARTIAL)) != 0) { vm_map_pmap_enter(map, start, prot, object, OFF_TO_IDX(offset), @@ -2083,34 +2084,24 @@ } /* - * vm_map_simplify_entry: + * vm_map_try_merge_entries: * - * Simplify the given map entry by merging with either neighbor. This - * routine also has the ability to merge with both neighbors. + * Compare the given map entry to its predecessor, and merge its precessor + * into it if possible. The entry remains valid, and may be extended. + * The predecessor may be deleted. * * The map must be locked. - * - * This routine guarantees that the passed entry remains valid (though - * possibly extended). When merging, this routine may delete one or - * both neighbors. */ void -vm_map_simplify_entry(vm_map_t map, vm_map_entry_t entry) +vm_map_try_merge_entries(vm_map_t map, vm_map_entry_t prev, vm_map_entry_t entry) { - vm_map_entry_t next, prev; - if ((entry->eflags & MAP_ENTRY_NOMERGE_MASK) != 0) - return; - prev = entry->prev; - if (vm_map_mergeable_neighbors(prev, entry)) { + VM_MAP_ASSERT_LOCKED(map); + if ((entry->eflags & MAP_ENTRY_NOMERGE_MASK) == 0 && + vm_map_mergeable_neighbors(prev, entry)) { vm_map_entry_unlink(map, prev, UNLINK_MERGE_NEXT); vm_map_merged_neighbor_dispose(map, prev); } - next = entry->next; - if (vm_map_mergeable_neighbors(entry, next)) { - vm_map_entry_unlink(map, next, UNLINK_MERGE_PREV); - vm_map_merged_neighbor_dispose(map, next); - } } /* @@ -2580,7 +2571,8 @@ * [Note that clipping is not necessary the second time.] */ for (current = entry; current->start < end; - vm_map_simplify_entry(map, current), current = current->next) { + vm_map_try_merge_entries(map, current->prev, current), + current = current->next) { if (rv != KERN_SUCCESS || (current->eflags & MAP_ENTRY_GUARD) != 0) continue; @@ -2618,6 +2610,7 @@ #undef MASK } } + vm_map_try_merge_entries(map, current->prev, current); vm_map_unlock(map); return (rv); } @@ -2722,8 +2715,9 @@ default: break; } - vm_map_simplify_entry(map, current); + vm_map_try_merge_entries(map, current->prev, current); } + vm_map_try_merge_entries(map, current->prev, current); vm_map_unlock(map); } else { vm_pindex_t pstart, pend; @@ -2837,9 +2831,10 @@ if ((entry->eflags & MAP_ENTRY_GUARD) == 0 || new_inheritance != VM_INHERIT_ZERO) entry->inheritance = new_inheritance; - vm_map_simplify_entry(map, entry); + vm_map_try_merge_entries(map, entry->prev, entry); entry = entry->next; } + vm_map_try_merge_entries(map, entry->prev, entry); vm_map_unlock(map); return (KERN_SUCCESS); } @@ -3016,8 +3011,9 @@ entry->eflags &= ~MAP_ENTRY_NEEDS_WAKEUP; need_wakeup = true; } - vm_map_simplify_entry(map, entry); + vm_map_try_merge_entries(map, entry->prev, entry); } + vm_map_try_merge_entries(map, entry->prev, entry); vm_map_unlock(map); if (need_wakeup) vm_map_wakeup(map); @@ -3313,8 +3309,9 @@ entry->eflags &= ~MAP_ENTRY_NEEDS_WAKEUP; need_wakeup = true; } - vm_map_simplify_entry(map, entry); + vm_map_try_merge_entries(map, entry->prev, entry); } + vm_map_try_merge_entries(map, entry->prev, entry); if (need_wakeup) vm_map_wakeup(map); return (rv); @@ -3952,8 +3949,8 @@ old_entry->object.vm_object); /* - * As in vm_map_simplify_entry(), the - * vnode lock will not be acquired in + * As in vm_map_merged_neighbor_dispose(), + * the vnode lock will not be acquired in * this call to vm_object_deallocate(). */ vm_object_deallocate(object);