Index: sys/vm/vm_map.c =================================================================== --- sys/vm/vm_map.c +++ sys/vm/vm_map.c @@ -898,7 +898,7 @@ { vm_map_entry_t llist, rlist; vm_map_entry_t ltree, rtree; - vm_map_entry_t y; + vm_map_entry_t x, y; /* Special case of empty tree. */ if (root == NULL) @@ -914,46 +914,81 @@ */ llist = NULL; rlist = NULL; - for (;;) { - /* root is never NULL in here. */ - if (addr < root->start) { - y = root->left; - if (y == NULL) - break; - if (addr < y->start && y->left != NULL) { - /* Rotate right and put y on rlist. */ - root->left = y->right; - y->right = root; - vm_map_entry_set_max_free(root); + do { + x = root; + /* x is never NULL in here. */ + if (addr >= x->end) { + y = x->right; + if (y != NULL && addr >= y->end) { + root = y->right; + /* Put y on llist. */ + y->right = llist; + llist = y; + /* Rotate left. */ + x->right = y->left; + y->left = x; + vm_map_entry_set_max_free(x); + } else if (y != NULL && addr < y->start) { root = y->left; + /* Put y on rlist */ y->left = rlist; rlist = y; + /* Put x on llist. */ + x->right = llist; + llist = x; } else { - /* Put root on rlist. */ - root->left = rlist; - rlist = root; root = y; - } - } else if (addr >= root->end) { - y = root->right; - if (y == NULL) + /* Put x on llist. */ + x->right = llist; + llist = x; break; - if (addr >= y->end && y->right != NULL) { - /* Rotate left and put y on llist. */ - root->right = y->left; - y->left = root; - vm_map_entry_set_max_free(root); + } + } else if (addr < x->start) { + y = x->left; + if (y != NULL && addr >= y->end) { root = y->right; + /* Put y on llist. */ y->right = llist; llist = y; + /* Put x on rlist. */ + x->left = rlist; + rlist = x; + } else if (y != NULL && addr < y->start) { + root = y->left; + /* Put y on rlist. */ + y->left = rlist; + rlist = y; + /* Rotate right. */ + x->left = y->right; + y->right = x; + vm_map_entry_set_max_free(x); } else { - /* Put root on llist. */ - root->right = llist; - llist = root; root = y; + /* Put x on rlist. */ + x->left = rlist; + rlist = x; + break; } } else break; + } while (root != NULL); + + if (root == NULL) { + /* + * With no matching node found, recover the greatest + * node in the left subtree and make it the root. + * If there is no such node, recover the least node from + * the right subtree. + */ + if (llist != NULL) { + root = llist; + llist = root->right; + root->right = NULL; + } else { + root = rlist; + rlist = root->left; + root->left = NULL; + } } /*