- fix a reversed comparison.

- fix "nextgap" case.
- make sure don't get addresses behind hint.
- deal with integer wraparounds better.
- assertions.
This commit is contained in:
yamt 2003-11-05 15:09:09 +00:00
parent 664bce39ae
commit 171053e863
1 changed files with 46 additions and 14 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: uvm_map.c,v 1.147 2003/11/02 07:58:52 yamt Exp $ */ /* $NetBSD: uvm_map.c,v 1.148 2003/11/05 15:09:09 yamt Exp $ */
/* /*
* Copyright (c) 1997 Charles D. Cranor and Washington University. * Copyright (c) 1997 Charles D. Cranor and Washington University.
@ -71,7 +71,7 @@
*/ */
#include <sys/cdefs.h> #include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: uvm_map.c,v 1.147 2003/11/02 07:58:52 yamt Exp $"); __KERNEL_RCSID(0, "$NetBSD: uvm_map.c,v 1.148 2003/11/05 15:09:09 yamt Exp $");
#include "opt_ddb.h" #include "opt_ddb.h"
#include "opt_uvmhist.h" #include "opt_uvmhist.h"
@ -1421,16 +1421,20 @@ uvm_map_findspace(struct vm_map *map, vaddr_t hint, vsize_t length,
goto wraparound; goto wraparound;
} }
if (topdown) if (topdown) {
/* /*
* Still there is a chance to fit * Still there is a chance to fit
* if hint > entry->end. * if hint > entry->end.
*/ */
; } else {
else /* Start from higer gap. */
entry = entry->next;
if (entry == &map->header)
goto notfound;
goto nextgap; goto nextgap;
} }
} }
}
/* /*
* Note that all UVM_FLAGS_FIXED case is already handled. * Note that all UVM_FLAGS_FIXED case is already handled.
@ -1450,6 +1454,7 @@ uvm_map_findspace(struct vm_map *map, vaddr_t hint, vsize_t length,
} }
nextgap: nextgap:
KDASSERT((flags & UVM_FLAG_FIXED) == 0);
/* If there is not enough space in the whole tree, we fail */ /* If there is not enough space in the whole tree, we fail */
tmp = RB_ROOT(&map->rbhead); tmp = RB_ROOT(&map->rbhead);
if (tmp == NULL || tmp->space < length) if (tmp == NULL || tmp->space < length)
@ -1496,17 +1501,23 @@ nextgap:
tmp = child; tmp = child;
} }
if (tmp != NULL && hint < tmp->end + tmp->ownspace) { if (tmp != NULL && tmp->start < hint && hint < tmp->next->start) {
/* /*
* Check if the entry that we found satifies the * Check if the entry that we found satifies the
* space requirement * space requirement
*/ */
if (hint < tmp->end || hint < tmp->end + tmp->ownspace - length) if (topdown) {
hint = topdown ? tmp->next->start - length : tmp->end; hint = tmp->next->start - length;
if (uvm_map_space_avail(&hint, length, uoffset, align, } else {
topdown, tmp) == 1) { hint = tmp->end;
}
switch (uvm_map_space_avail(&hint, length, uoffset, align,
topdown, tmp)) {
case 1:
entry = tmp; entry = tmp;
goto found; goto found;
case -1:
goto wraparound;
} }
if (tmp->ownspace >= length) if (tmp->ownspace >= length)
goto listsearch; goto listsearch;
@ -1514,11 +1525,21 @@ nextgap:
if (prev == NULL) if (prev == NULL)
goto notfound; goto notfound;
hint = topdown ? prev->next->start - length : prev->end; if (topdown) {
if (uvm_map_space_avail(&hint, length, uoffset, align, topdown, prev) KASSERT(hint >= prev->next->start - length ||
== 1) { prev->next->start - length > prev->next->start);
hint = prev->next->start - length;
} else {
KASSERT(hint <= prev->end);
hint = prev->end;
}
switch (uvm_map_space_avail(&hint, length, uoffset, align,
topdown, prev)) {
case 1:
entry = prev; entry = prev;
goto found; goto found;
case -1:
goto wraparound;
} }
if (prev->ownspace >= length) if (prev->ownspace >= length)
goto listsearch; goto listsearch;
@ -1545,12 +1566,21 @@ nextgap:
tmp = RB_RIGHT(tmp, rb_entry); tmp = RB_RIGHT(tmp, rb_entry);
} }
hint = topdown ? tmp->next->start - length : tmp->end; if (topdown) {
KASSERT(hint >= tmp->next->start - length ||
tmp->next->start - length > tmp->next->start);
hint = tmp->next->start - length;
} else {
KASSERT(hint <= tmp->end);
hint = tmp->end;
}
switch (uvm_map_space_avail(&hint, length, uoffset, align, switch (uvm_map_space_avail(&hint, length, uoffset, align,
topdown, tmp)) { topdown, tmp)) {
case 1: case 1:
entry = tmp; entry = tmp;
goto found; goto found;
case -1:
goto wraparound;
} }
/* /*
@ -1600,6 +1630,8 @@ nextgap:
SAVE_HINT(map, map->hint, entry); SAVE_HINT(map, map->hint, entry);
*result = hint; *result = hint;
UVMHIST_LOG(maphist,"<- got it! (result=0x%x)", hint, 0,0,0); UVMHIST_LOG(maphist,"<- got it! (result=0x%x)", hint, 0,0,0);
KASSERT( topdown || hint >= orig_hint);
KASSERT(!topdown || hint <= orig_hint);
KASSERT(entry->end <= hint); KASSERT(entry->end <= hint);
KASSERT(hint + length <= entry->next->start); KASSERT(hint + length <= entry->next->start);
return (entry); return (entry);