[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Xen-devel] [PATCH v3 12/16 - RFC] x86/efi: create new early memory allocator

On Fri, Apr 15, 2016 at 02:33:12PM +0200, Daniel Kiper wrote:
> There is a problem with place_string() which is used as early memory
> allocator. It gets memory chunks starting from start symbol and
> going down. Sadly this does not work when Xen is loaded using multiboot2
> protocol because start lives on 1 MiB address. So, I tried to use
> mem_lower address calculated by GRUB2. However, it works only on some
> machines. There are machines in the wild (e.g. Dell PowerEdge R820)
> which uses first ~640 KiB for boot services code or data... :-(((
> In case of multiboot2 protocol we need that place_string() only allocate
> memory chunk for EFI memory map. However, I think that it should be fixed
> instead of making another function used just in one case. I thought about
> two solutions.

I have done more experiments, read more code, etc. You can find results below.

> 1) We could use native EFI allocation functions (e.g. AllocatePool()
>    or AllocatePages()) to get memory chunk. However, later (somewhere
>    in __start_xen()) we must copy its contents to safe place or reserve
>    this in e820 memory map and map it in Xen virtual address space.

I have checked Linux kernel code. It allocates buffer for memory map using
EFI API and later reserve it in e820 memory map. Simple. This should work
for us too but...

>    In later case we must also care about conflicts with e.g. crash
>    kernel regions which could be quite difficult.

This is not a problem since Xen can choose dynamically placement of kdump
region during boot phase and there is no requirement to specify it in boot
command line. This means that it will avoid all allocated/reserved regions
including EFI memory map. However, there is one potential problem which
cannot be avoided simply with current EFI spec. I think about conflicts
with trampoline. It must live below 1 MiB. However, there is not something
similar to "AllocateMaxAddress" option for AllocatePages() which would
ask EFI to allocate memory above a given address (Hmmm... Why UEFI designers
did not added such option, e.g. "AllocateMinAddress"? For me it is obvious
thing if we have "AllocateMaxAddress"). So, it means that we cannot simply
say "give me a memory chunk above 1 MiB". AIUI, Linux guys do not care,
hope that all EFI platforms are smart and AllocatePages() tries hard to
avoid everything below 1 MiB. We can go this way too. However, I am almost
sure that sooner or later we will find crazy platforms which allocate memory
from 0-1 MiB region. We can avoid this by getting EFI memory map, looking for
free regions above 1 MiB and then trying to allocate memory chunk using
AllocatePages() with "AllocateAddress". Does it make sense?

> 2) We may allocate memory area statically somewhere in Xen code which
>    could be used as memory pool for early dynamic allocations. Looks
>    quite simple. Additionally, it would not depend on EFI at all and
>    could be used on legacy BIOS platforms if we need it. However, we
>    must carefully choose size of this pool. We do not want increase
>    Xen binary size too much and waste too much memory but also we must fit
>    at least memory map on x86 EFI platforms. As I saw on small machine,
>    e.g. IBM System x3550 M2 with 8 GiB RAM, memory map may contain more
>    than 200 entries. Every entry on x86-64 platform is 40 bytes in size.
>    So, it means that we need more than 8 KiB for EFI memory map only.
>    Additionally, if we want to use this memory pool for Xen and modules
>    command line storage (it would be used when xen.efi is executed as EFI
>    application) then we should add, I think, about 1 KiB. In this case,
>    to be on safe side, we should assume at least 64 KiB pool for early
>    memory allocations, which is about 4 times of our earlier calculations.
>    However, during discussion on Xen-devel Jan Beulich suggested that
>    just in case we should use 1 MiB memory pool like it was in original
>    place_string() implementation. So, let's use 1 MiB as it was proposed.
>    If we think that we should not waste unallocated memory in the pool
>    on running system then we can mark this region as __initdata and move
>    all required data to dynamically allocated places somewhere in 
> __start_xen().

2a) We can create something like .init.bss and put this thing at the end of
    regular .bss section. Then allocate memory chunks starting from lowest
    address. After init phase we can free unused memory as in case of .init.text
    or .init.data sections. This way we do not need allocate any space in
    image file and freeing of unused memory should be simple. What do you
    think about that one?


Xen-devel mailing list



Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.