Page MenuHomeFreeBSD

D19826.id55898.diff
No OneTemporary

D19826.id55898.diff

Index: sys/vm/vm_map.c
===================================================================
--- sys/vm/vm_map.c
+++ sys/vm/vm_map.c
@@ -917,36 +917,52 @@
entry->max_free = MAX(max_left, max_right);
}
-#define SPLAY_LEFT_STEP(root, y, rlist, test) do { \
- y = root->left; \
- if (y != NULL && (test)) { \
- /* Rotate right and make y root. */ \
- root->left = y->right; \
- y->right = root; \
- vm_map_entry_set_max_free(root); \
- root = y; \
- y = root->left; \
- } \
- /* Put root on rlist. */ \
- root->left = rlist; \
- rlist = root; \
- root = y; \
+#define SPLAY_LEFT_STEP(root, y, rlist, test) do { \
+ y = root->left; \
+ if (y != NULL && (test)) { \
+ /* Rotate right and make y root. */ \
+ root->left = y->right; \
+ y->right = root; \
+ if (root->max_free == y->max_free) \
+ vm_map_entry_set_max_free(root); \
+ root = y; \
+ y = root->left; \
+ } \
+ /* Put root on rlist. */ \
+ root->left = rlist; \
+ rlist = root; \
+ root = y; \
+ /* Make rlist->max_free match max_free for its right child. */ \
+ if (broken || rlist->max_free == ((root != NULL) ? \
+ root->max_free : rlist->start - rlist->prev->end)) { \
+ y = rlist->right; \
+ rlist->max_free = (y != NULL) ? \
+ y->max_free : rlist->next->start - rlist->end; \
+ } \
} while (0)
-#define SPLAY_RIGHT_STEP(root, y, llist, test) do { \
- y = root->right; \
- if (y != NULL && (test)) { \
- /* Rotate left and make y root. */ \
- root->right = y->left; \
- y->left = root; \
- vm_map_entry_set_max_free(root); \
- root = y; \
- y = root->right; \
- } \
- /* Put root on llist. */ \
- root->right = llist; \
- llist = root; \
- root = y; \
+#define SPLAY_RIGHT_STEP(root, y, llist, test) do { \
+ y = root->right; \
+ if (y != NULL && (test)) { \
+ /* Rotate left and make y root. */ \
+ root->right = y->left; \
+ y->left = root; \
+ if (root->max_free == y->max_free) \
+ vm_map_entry_set_max_free(root); \
+ root = y; \
+ y = root->right; \
+ } \
+ /* Put root on llist. */ \
+ root->right = llist; \
+ llist = root; \
+ root = y; \
+ /* Make llist->max_free match max_free for its left child. */ \
+ if (broken || llist->max_free == ((root != NULL) ? \
+ root->max_free : llist->next->start - llist->end)) { \
+ y = llist->left; \
+ llist->max_free = (y != NULL) ? \
+ y->max_free : llist->start - llist->prev->end; \
+ } \
} while (0)
/*
@@ -959,7 +975,7 @@
*/
static vm_map_entry_t
vm_map_splay_split(vm_offset_t addr, vm_size_t length,
- vm_map_entry_t root, vm_map_entry_t *out_llist, vm_map_entry_t *out_rlist)
+ vm_map_entry_t root, vm_map_entry_t *out_llist, vm_map_entry_t *out_rlist, bool broken)
{
vm_map_entry_t llist, rlist;
vm_map_entry_t y;
@@ -982,7 +998,7 @@
}
static void
-vm_map_splay_findnext(vm_map_entry_t root, vm_map_entry_t *iolist)
+vm_map_splay_findnext(vm_map_entry_t root, vm_map_entry_t *iolist, bool broken)
{
vm_map_entry_t rlist, y;
@@ -994,7 +1010,7 @@
}
static void
-vm_map_splay_findprev(vm_map_entry_t root, vm_map_entry_t *iolist)
+vm_map_splay_findprev(vm_map_entry_t root, vm_map_entry_t *iolist, bool broken)
{
vm_map_entry_t llist, y;
@@ -1015,18 +1031,31 @@
vm_map_entry_t ltree, vm_map_entry_t rtree)
{
vm_map_entry_t y;
+ vm_size_t max_free;
+ if (llist != NULL)
+ max_free = (ltree != NULL) ? ltree->max_free :
+ llist->next->start - llist->end;
while (llist != NULL) {
y = llist->right;
llist->right = ltree;
- vm_map_entry_set_max_free(llist);
+ if (llist->max_free < max_free)
+ llist->max_free = max_free;
+ else
+ max_free = llist->max_free;
ltree = llist;
llist = y;
}
+ if (rlist != NULL)
+ max_free = (rtree != NULL) ? rtree->max_free :
+ rlist->start - rlist->prev->end;
while (rlist != NULL) {
y = rlist->left;
rlist->left = rtree;
- vm_map_entry_set_max_free(rlist);
+ if (rlist->max_free < max_free)
+ rlist->max_free = max_free;
+ else
+ max_free = rlist->max_free;
rtree = rlist;
rlist = y;
}
@@ -1062,8 +1091,9 @@
vm_map_entry_splay(vm_offset_t addr, vm_map_entry_t root)
{
vm_map_entry_t llist, rlist;
+ bool broken = false;
- root = vm_map_splay_split(addr, 0, root, &llist, &rlist);
+ root = vm_map_splay_split(addr, 0, root, &llist, &rlist, broken);
if (root != NULL) {
/* do nothing */
} else if (llist != NULL) {
@@ -1100,6 +1130,7 @@
vm_map_entry_t entry)
{
vm_map_entry_t llist, rlist, root;
+ bool broken = true;
CTR3(KTR_VM,
"vm_map_entry_link: map %p, nentries %d, entry %p", map,
@@ -1107,7 +1138,7 @@
VM_MAP_ASSERT_LOCKED(map);
map->nentries++;
root = map->root;
- root = vm_map_splay_split(entry->start, 0, root, &llist, &rlist);
+ root = vm_map_splay_split(entry->start, 0, root, &llist, &rlist, broken);
KASSERT(root == NULL,
("vm_map_entry_link: link object already mapped"));
entry->prev = (llist == NULL) ? &map->header : llist;
@@ -1130,20 +1161,17 @@
enum unlink_merge_type op)
{
vm_map_entry_t llist, rlist, root, y;
+ bool broken = true;
VM_MAP_ASSERT_LOCKED(map);
- llist = entry->prev;
- rlist = entry->next;
- llist->next = rlist;
- rlist->prev = llist;
root = map->root;
- root = vm_map_splay_split(entry->start, 0, root, &llist, &rlist);
+ root = vm_map_splay_split(entry->start, 0, root, &llist, &rlist, broken);
KASSERT(root != NULL,
("vm_map_entry_unlink: unlink object not mapped"));
switch (op) {
case UNLINK_MERGE_PREV:
- vm_map_splay_findprev(root, &llist);
+ vm_map_splay_findprev(root, &llist, broken);
llist->end = root->end;
y = root->right;
root = llist;
@@ -1151,7 +1179,7 @@
root->right = y;
break;
case UNLINK_MERGE_NEXT:
- vm_map_splay_findnext(root, &rlist);
+ vm_map_splay_findnext(root, &rlist, broken);
rlist->start = root->start;
rlist->offset = root->offset;
y = root->left;
@@ -1160,8 +1188,8 @@
root->left = y;
break;
case UNLINK_MERGE_NONE:
- vm_map_splay_findprev(root, &llist);
- vm_map_splay_findnext(root, &rlist);
+ vm_map_splay_findprev(root, &llist, broken);
+ vm_map_splay_findnext(root, &rlist, broken);
if (llist != NULL) {
root = llist;
llist = root->right;
@@ -1174,6 +1202,9 @@
root = NULL;
break;
}
+ y = entry->next;
+ y->prev = entry->prev;
+ y->prev->next = y;
if (root != NULL)
root = vm_map_splay_merge(root, llist, rlist,
root->left, root->right);
@@ -1195,17 +1226,19 @@
* The map must be locked, and leaves it so.
*/
static void
-vm_map_entry_resize_free(vm_map_t map, vm_map_entry_t entry)
+vm_map_entry_resize_free(vm_map_t map, vm_map_entry_t entry, vm_offset_t addToEnd)
{
vm_map_entry_t llist, rlist, root;
+ bool broken = true;
VM_MAP_ASSERT_LOCKED(map);
root = map->root;
- root = vm_map_splay_split(entry->start, 0, root, &llist, &rlist);
+ root = vm_map_splay_split(entry->start, 0, root, &llist, &rlist, broken);
KASSERT(root != NULL,
("vm_map_entry_resize_free: resize_free object not mapped"));
- vm_map_splay_findnext(root, &rlist);
+ vm_map_splay_findnext(root, &rlist, broken);
root->right = NULL;
+ entry->end += addToEnd;
map->root = vm_map_splay_merge(root, llist, rlist,
root->left, root->right);
VM_MAP_ASSERT_CONSISTENT(map);
@@ -1427,8 +1460,8 @@
prev_entry));
if ((prev_entry->eflags & MAP_ENTRY_GUARD) == 0)
map->size += end - prev_entry->end;
- prev_entry->end = end;
- vm_map_entry_resize_free(map, prev_entry);
+ vm_map_entry_resize_free(map, prev_entry,
+ end - prev_entry->end);
vm_map_simplify_entry(map, prev_entry);
return (KERN_SUCCESS);
}
@@ -1521,6 +1554,7 @@
{
vm_map_entry_t llist, rlist, root, y;
vm_size_t left_length;
+ bool broken = true;
/*
* Request must fit within min/max VM address and must avoid
@@ -1539,7 +1573,7 @@
* must be a gap from start to the root.
*/
root = vm_map_splay_split(start, length, map->root,
- &llist, &rlist);
+ &llist, &rlist, broken);
if (root != NULL)
start = root->end;
else if (rlist != NULL) {
@@ -4181,25 +4215,20 @@
gap_deleted = true;
} else {
MPASS(gap_entry->start < gap_entry->end - grow_amount);
- gap_entry->end -= grow_amount;
- vm_map_entry_resize_free(map, gap_entry);
+ vm_map_entry_resize_free(map, gap_entry, -grow_amount);
gap_deleted = false;
}
rv = vm_map_insert(map, NULL, 0, grow_start,
grow_start + grow_amount,
stack_entry->protection, stack_entry->max_protection,
MAP_STACK_GROWS_DOWN);
- if (rv != KERN_SUCCESS) {
- if (gap_deleted) {
- rv1 = vm_map_insert(map, NULL, 0, gap_start,
- gap_end, VM_PROT_NONE, VM_PROT_NONE,
- MAP_CREATE_GUARD | MAP_CREATE_STACK_GAP_DN);
- MPASS(rv1 == KERN_SUCCESS);
- } else {
- gap_entry->end += grow_amount;
- vm_map_entry_resize_free(map, gap_entry);
- }
- }
+ if (rv != KERN_SUCCESS && gap_deleted) {
+ rv1 = vm_map_insert(map, NULL, 0, gap_start,
+ gap_end, VM_PROT_NONE, VM_PROT_NONE,
+ MAP_CREATE_GUARD | MAP_CREATE_STACK_GAP_DN);
+ MPASS(rv1 == KERN_SUCCESS);
+ } else if (rv != KERN_SUCCESS)
+ vm_map_entry_resize_free(map, gap_entry, grow_amount);
} else {
grow_start = stack_entry->end;
cred = stack_entry->cred;
@@ -4213,13 +4242,14 @@
stack_entry->offset,
(vm_size_t)(stack_entry->end - stack_entry->start),
(vm_size_t)grow_amount, cred != NULL)) {
- if (gap_entry->start + grow_amount == gap_entry->end)
+ if (gap_entry->start + grow_amount == gap_entry->end) {
vm_map_entry_delete(map, gap_entry);
- else
+ vm_map_entry_resize_free(map, stack_entry, grow_amount);
+ } else {
gap_entry->start += grow_amount;
- stack_entry->end += grow_amount;
+ stack_entry->end += grow_amount;
+ }
map->size += grow_amount;
- vm_map_entry_resize_free(map, stack_entry);
rv = KERN_SUCCESS;
} else
rv = KERN_FAILURE;

File Metadata

Mime Type
text/plain
Expires
Tue, Oct 28, 7:19 AM (20 h, 10 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
24345598
Default Alt Text
D19826.id55898.diff (9 KB)

Event Timeline