* vm/vm_map.c: if the start address is not in the map, try to find the
nearest entry instead of failing.
This caused the initial vm_wire_all(host, task VM_WIRE_ALL) in glibc
startup to fail with KERN_NO_SPACE.
---
vm/vm_map.c | 21 ++++++++++++++++-----
1 file changed, 16 insertions(+), 5 deletions(-)
diff --git a/vm/vm_map.c b/vm/vm_map.c
index 26e18676..4a5861e3 100644
--- a/vm/vm_map.c
+++ b/vm/vm_map.c
@@ -1774,13 +1774,24 @@ kern_return_t vm_map_pageable(
if (!vm_map_lookup_entry(map, start, &start_entry)) {
/*
- * Start address is not in map; this is fatal.
+ * Start address is not in map; try to find the nearest
entry
*/
- if (lock_map) {
- vm_map_unlock(map);
- }
+ struct rbtree_node *node;
+ node = rbtree_lookup_nearest(&map->hdr.tree, start,
+ vm_map_entry_cmp_lookup,
RBTREE_LEFT);
+
+ if (node == NULL) {
+ node = rbtree_lookup_nearest(&map->hdr.tree, start,
+ vm_map_entry_cmp_lookup,
RBTREE_RIGHT);
+ if (node == NULL) {
+ if (lock_map) {
+ vm_map_unlock(map);
+ }
+ return KERN_NO_SPACE;
+ }
- return KERN_NO_SPACE;
+ }
+ start_entry = rbtree_entry(node, struct vm_map_entry,
tree_node);
}
/*
--
2.39.2