arena: do not round-up when picking xalloc lists
The list we start at is an optimization. We could easily start at the
first list. We skip to the first list that *can* satisfy us.
Previously, due to align and phase acrobatics, we could jump to the next
list beyond the one that could satisfy us, which could lead to an "OOM"
when we actually had the resource.
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
diff --git a/kern/src/arena.c b/kern/src/arena.c
index 267871f..e4ac586 100644
--- a/kern/src/arena.c
+++ b/kern/src/arena.c
@@ -899,9 +899,10 @@
struct btag *bt_i;
uintptr_t try = 0;
- if (ROUNDUP(size, align) + phase < size)
- return NULL;
- list_idx = LOG2_DOWN(ROUNDUP(size, align) + phase);
+ /* This starting list_idx is an optimization. We could scan all the
+ * lists. You can't round-up size and add phase, because that could
+ * cross a power-of-two boundary and skip the one list that works. */
+ list_idx = LOG2_DOWN(size);
list_idx += try_instant_fit ? 1 : 0;
for (int i = list_idx; i < ARENA_NR_FREE_LISTS; i++) {
BSD_LIST_FOREACH(bt_i, &arena->free_segs[i], misc_link) {