Index: sys/vm/vm_map.h =================================================================== --- sys/vm/vm_map.h +++ sys/vm/vm_map.h @@ -106,7 +106,6 @@ vm_offset_t start; /* start address */ vm_offset_t end; /* end address */ vm_offset_t next_read; /* vaddr of the next sequential read */ - vm_size_t adj_free; /* amount of adjacent free space */ vm_size_t max_free; /* max free space in subtree */ union vm_map_object object; /* object I point to */ vm_ooffset_t offset; /* offset into object */ Index: sys/vm/vm_map.c =================================================================== --- sys/vm/vm_map.c +++ sys/vm/vm_map.c @@ -869,12 +869,13 @@ static inline void vm_map_entry_set_max_free(vm_map_entry_t entry) { + vm_size_t max_left, max_right; - entry->max_free = entry->adj_free; - if (entry->left != NULL && entry->left->max_free > entry->max_free) - entry->max_free = entry->left->max_free; - if (entry->right != NULL && entry->right->max_free > entry->max_free) - entry->max_free = entry->right->max_free; + max_left = (entry->left != NULL) ? entry->left->max_free : + entry->start - entry->prev->end; + max_right = (entry->right != NULL) ? entry->right->max_free : + entry->next->start - entry->end; + entry->max_free = MAX(max_left, max_right); } /* @@ -1023,13 +1024,11 @@ entry->right = after_where->right; entry->left = after_where; after_where->right = NULL; - after_where->adj_free = entry->start - after_where->end; vm_map_entry_set_max_free(after_where); } else { entry->right = map->root; entry->left = NULL; } - entry->adj_free = entry->next->start - entry->end; vm_map_entry_set_max_free(entry); map->root = entry; } @@ -1048,7 +1047,6 @@ else { root = vm_map_entry_splay(entry->start, entry->left); root->right = entry->right; - root->adj_free = entry->next->start - root->end; vm_map_entry_set_max_free(root); } map->root = root; @@ -1084,7 +1082,6 @@ if (entry != map->root) map->root = vm_map_entry_splay(entry->start, map->root); - entry->adj_free = entry->next->start - entry->end; vm_map_entry_set_max_free(entry); } @@ -1381,11 +1378,11 @@ * Find the first fit (lowest VM address) for "length" free bytes * beginning at address >= start in the given map. * - * In a vm_map_entry, "adj_free" is the amount of free space - * adjacent (higher address) to this entry, and "max_free" is the - * maximum amount of contiguous free space in its subtree. This - * allows finding a free region in one path down the tree, so - * O(log n) amortized with splay trees. + * In a vm_map_entry, "max_free" is the maximum amount of + * contiguous free space between an entry in its subtree and a + * neighbor of that entry. This allows finding a free region in + * one path down the tree, so O(log n) amortized with splay + * trees. * * The map must be locked, and leaves it so. * @@ -1397,7 +1394,6 @@ vm_offset_t *addr) /* OUT */ { vm_map_entry_t entry; - vm_offset_t st; /* * Request must fit within min/max VM address and must avoid @@ -1428,14 +1424,15 @@ * start, and this is the last comparison where address * wrap might be a problem. */ - st = (start > map->root->end) ? start : map->root->end; - if (length <= map->root->end + map->root->adj_free - st) { - *addr = st; + entry = map->root; + start = MAX(start, entry->end); + if (length <= entry->next->start - start) { + *addr = start; return (0); } /* With max_free, can immediately tell if no solution. */ - entry = map->root->right; + entry = entry->right; if (entry == NULL || length > entry->max_free) return (1); @@ -1447,11 +1444,16 @@ while (entry != NULL) { if (entry->left != NULL && entry->left->max_free >= length) entry = entry->left; - else if (entry->adj_free >= length) { - *addr = entry->end; + else if (entry->left == NULL && + entry->start - entry->prev->end >= length) { + *addr = entry->prev->end; return (0); - } else + } else if (entry->right != NULL) entry = entry->right; + else { + *addr = entry->end; + return (0); + } } /* Can't get here, so panic if we do. */