On Mon, Dec 10, 2018 at 08:30:10AM +0100, Otto Moerbeek wrote:

> 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

As it turns out by my own testing, on amd64 root filssytems using 32k
blocks now work fine, but 64k fs blocks still hit a ceiling. This
corresponds to > 512G disks if you use the defaults.

        -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