arena: do not round-up when picking xalloc lists
authorBarret Rhoden <brho@cs.berkeley.edu>
Mon, 23 Sep 2019 20:20:32 +0000 (16:20 -0400)
committerBarret Rhoden <brho@cs.berkeley.edu>
Tue, 8 Oct 2019 21:11:11 +0000 (17:11 -0400)
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>
kern/src/arena.c

index 267871f..e4ac586 100644 (file)
@@ -899,9 +899,10 @@ static void *__xalloc_from_freelists(struct arena *arena, size_t size,
        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) {