Hi,

the bootloader uses a very simple allocator for dynamic memory. It
maintains a list of free allocations. If it needs a block, it searches
the freelist and returns the smallest allocation that fits.

Allocation patterns like this (starting with an empty freelist)

alloc(big)
free(big)
alloc(small)

will assigned a big block for the small allocation, wasting most
memory. The allocator does not split up this block. After this, a new
big allocation will grow the heap with the big amount. This diff
changes the strategy by not re-using a block from the free list if
half the space or more would be wasted. Instead, it grows the heap by
the requested amount.

This make it possible for me to boot using a root fs with a large
blocksize. There have been several reports of large roots not working
(the bootloader allocates memory based om the blocksize of the file
system, and by default larger filesystems use larger blocks).

How to test
===========

Apply diff and do a full build including building release. After that,
either upgrade using your newly built cd64.iso, bsd.rd or other
mechanism or do a full install. Test that you can boot afterwards.

This needs to be tested on various platforms, both will small and big
(> 600G) root filesystems.  Yes, this is tedious, but we want large
coverage of different cases.

        -Otto

Index: alloc.c
===================================================================
RCS file: /cvs/src/sys/lib/libsa/alloc.c,v
retrieving revision 1.12
diff -u -p -r1.12 alloc.c
--- alloc.c     14 Mar 2016 23:08:06 -0000      1.12
+++ alloc.c     10 Dec 2018 06:37:28 -0000
@@ -169,7 +169,7 @@ alloc(unsigned int size)
        }
 
        /* no match in freelist if bestsize unchanged */
-       failed = (bestsize == 0xffffffff);
+       failed = (bestsize == 0xffffffff || bestsize >= size * 2);
 #endif
 
        if (failed) { /* nothing found */


Reply via email to