Boot time memory management

https://www.kernel.org/doc/html/latest/core-api/boot-time-mm.html

Boot time memory management

Early system initialization cannot use “normal” memory management simply because it is not set up yet. But there is still need to allocate memory for various data structures, for instance for the physical page allocator.

Immediately after starting system initialization, a regular memory manager is simply not available, because it is not ready yet. However, you need to allocate memory for various data structures, for example physical page allocator.

A specialized allocator called memblock performs the boot time memory management. The architecture specific initialization must set it up in setup_arch() and tear it down in mem_init() functions.

A special allocator called memblock performs memory management at startup. For architecture-specific initialization, you need to configure it with setup_arch () and destroy it with the mem_init () function.

Once the early memory management is available it offers a variety of functions and macros for memory allocations. The allocation request may be directed to the first (and probably the only) node or to a particular node in a NUMA system. There are API variants that panic when an allocation fails and those that don’t.

Once early memory management is enabled, various functions and macros for memory allocations will be enabled. The allocation is sent to the first (and probably the only) node or a specific node in the NUMA system. Some APIs will panic when the allocation fails, while others will not.

Memblock also offers a variety of APIs that control its own behaviour.

Memblock also provides various APIs for controlling self-confidence behavior.

Memblock Overview

Memblock is a method of managing memory regions during the early boot period when the usual kernel memory allocators are not up and running.

Memblock is a method of managing the memory region in the early boot period when the kernel memory allocatior will not normally start or operate.

Memblock views the system memory as collections of contiguous regions. There are several types of these collections:

Memblock sees system memroy as a set of contiguous regions. There are several types of these sets.

・ Memory --describes the physical memory available to the kernel; this may differ from the actual physical memory installed in the system, for instance when the memory is restricted with mem = command line parameter ・ Reserved --describes the regions that were allocated ・ Physmap --describes the actual physical memory regardless of the possible restrictions; the physmap type is only available on some architectures.

· Memory--Describes physical memory for the kernel; this may differ from the physical memory actually installed in the system. For example, if it is restricted by mem = command line parameter. -Reserved-Describe a region that is already allocated. · Physmap-Describes the actual physical memory, regardless of possible limits. The physmap type is only available on some architectures.

Each region is represented by struct memblock_region that defines the region extents, its attributes and NUMA node id on NUMA systems. Every memory type is described by the struct memblock_type which contains an array of memory regions along with the allocator metadata. The memory types are nicely wrapped with struct memblock. This structure is statically initialzed at build time.

Each region is represented by the structure memblock_region, which defines the region range, its attributes, and the NUMA node id in the NUMA system. All memory types are described by struct memblock_type. It contains an array of memory regions, along with allocator metadata. The memory type nicely wraps the structure memblock. This structure is statically initialized at startup.

The region arrays for the “memory” and “reserved” types are initially sized to INIT_MEMBLOCK_REGIONS and for the “physmap” type to INIT_PHYSMEM_REGIONS. The memblock_allow_resize() enables automatic resizing of the region arrays during addition of new regions. This feature should be used with care so that memory allocated for the region array will not overlap with areas that should be reserved, for example initrd.

The "memory" and "reserved" type region arrays are initialized to the size of INIT_MEMBLOCK_REGIONS, and the "physmap" type is INIT_PHYSMEM_REGIONS. memblock_allow_resize () will automatically resize the region array while new regions are added. This feature should be careful so that the memory allocated to the region array does not overlap with the regions that need to be reserved, such as the initrd.

The early architecture setup should tell memblock what the physical memory layout is by using memblock_add() or memblock_add_node() functions. The first function does not assign the region to a NUMA node and it is appropriate for UMA systems. Yet, it is possible to use it on NUMA systems as well and assign the region to a NUMA node later in the setup process using memblock_set_node(). The memblock_add_node() performs such an assignment directly.

Early architectural setups need to use memblock_add () or memblock_add_node () functions to notify memblock of the physical memory layout, the first function does not allocate space for NUMA nodes, which is suitable for UMA systems. I am. However, it is also available on NUMA systems. Assign a NUMA node after running the setup process using memblock_set_node (). The memblock_add_node () makes such an assignment directly.

Once memblock is setup the memory can be allocated using one of the API variants:

Once the memory is set up with memblock, you can allocate the memory using one of the API variants.

・ Memblock_phys_alloc * () --these functions return the physical address of the allocated memory -Memblock_alloc * () --these functions return the virtual address of the allocated memory.

-Memblock_phys_alloc * () --These functions return the memory with the allocated physical address as the return value. · Memblock_alloc * ()-These functions return the virtual address of reserved memory.

Note, that both API variants use implict assumptions about allowed memory ranges and the fallback methods. Consult the documentation of memblock_alloc_internal() and memblock_alloc_range_nid() functions for more elaborate description.

Note that both API variants use an implicit process for the allowed memory range and fallback means. See the memblock_alloc_internal) and memblock_alloc_range_nid) function documentation for a more detailed explanation.

As the system boot progresses, the architecture specific mem_init() function frees all the memory to the buddy page allocator.

During system boot progress, the architecture-specific mem_init () function frees all memory for the buddy page allocator.

Unless an architecture enables CONFIG_ARCH_KEEP_MEMBLOCK, the memblock data structures will be discarded after the system initialization completes.

Unless the architecture enables CONFIG_ARCH_KEEP_MEMBLOCK, memblock data structures will be destroyed after system initialization is complete.

Recommended Posts

Boot time memory management
Memory Management »Concepts overview
[Translation] Spark Memory Management since 1.6.0
[OS / Linux] Process, thread, memory management