Index: head/sys/vm/vm_map.c =================================================================== --- head/sys/vm/vm_map.c +++ head/sys/vm/vm_map.c @@ -1644,16 +1644,25 @@ } } +/* + * A map entry with any of the following flags set must not be merged with + * another entry. + */ +#define MAP_ENTRY_NOMERGE_MASK (MAP_ENTRY_GROWS_DOWN | MAP_ENTRY_GROWS_UP | \ + MAP_ENTRY_IN_TRANSITION | MAP_ENTRY_IS_SUB_MAP) + static bool vm_map_mergeable_neighbors(vm_map_entry_t prev, vm_map_entry_t entry) { - vm_size_t prevsize; - prevsize = prev->end - prev->start; + KASSERT((prev->eflags & MAP_ENTRY_NOMERGE_MASK) == 0 || + (entry->eflags & MAP_ENTRY_NOMERGE_MASK) == 0, + ("vm_map_mergeable_neighbors: neither %p nor %p are mergeable", + prev, entry)); return (prev->end == entry->start && prev->object.vm_object == entry->object.vm_object && (prev->object.vm_object == NULL || - prev->offset + prevsize == entry->offset) && + prev->offset + (prev->end - prev->start) == entry->offset) && prev->eflags == entry->eflags && prev->protection == entry->protection && prev->max_protection == entry->max_protection && @@ -1667,18 +1676,14 @@ { /* - * If the backing object is a vnode object, - * vm_object_deallocate() calls vrele(). - * However, vrele() does not lock the vnode - * because the vnode has additional - * references. Thus, the map lock can be kept - * without causing a lock-order reversal with - * the vnode lock. + * If the backing object is a vnode object, vm_object_deallocate() + * calls vrele(). However, vrele() does not lock the vnode because + * the vnode has additional references. Thus, the map lock can be + * kept without causing a lock-order reversal with the vnode lock. * - * Since we count the number of virtual page - * mappings in object->un_pager.vnp.writemappings, - * the writemappings value should not be adjusted - * when the entry is disposed of. + * Since we count the number of virtual page mappings in + * object->un_pager.vnp.writemappings, the writemappings value + * should not be adjusted when the entry is disposed of. */ if (entry->object.vm_object != NULL) vm_object_deallocate(entry->object.vm_object); @@ -1704,10 +1709,8 @@ { vm_map_entry_t next, prev; - if ((entry->eflags & (MAP_ENTRY_GROWS_DOWN | MAP_ENTRY_GROWS_UP | - MAP_ENTRY_IN_TRANSITION | MAP_ENTRY_IS_SUB_MAP)) != 0) + if ((entry->eflags & MAP_ENTRY_NOMERGE_MASK) != 0) return; - prev = entry->prev; if (vm_map_mergeable_neighbors(prev, entry)) { vm_map_entry_unlink(map, prev); @@ -1717,7 +1720,6 @@ vm_map_entry_resize_free(map, entry->prev); vm_map_merged_neighbor_dispose(map, prev); } - next = entry->next; if (vm_map_mergeable_neighbors(entry, next)) { vm_map_entry_unlink(map, next); @@ -1726,6 +1728,7 @@ vm_map_merged_neighbor_dispose(map, next); } } + /* * vm_map_clip_start: [ internal use only ] *