Chapter3:MemoryManagement
Interfaceto the Kernel
Allocating Memory
The kernel provides a variety of functions for reserving memory during initialization. The following
functions are available on UMA systems:
❑ alloc_bootmem(size)andalloc_bootmem_pages(size)reserve memory whose size is
expressed bysizeinZONE_NORMAL; data are aligned so that memory begins either at an ideal
position for the L1 cache or on a page boundary.
Even though the namealloc_bootmem_pagessuggests that the required size is
specified in page units,_pagesrefers only to thealignmentof the data.
❑ alloc_bootmem_lowandalloc_bootmem_low_pagesoperate in the same ways as the above
functions but take the areaZONE_DMAthat is suitable for DMA operations as their source. Con-
sequently, the functions should only be used when DMA memory is required.
Basically the same API applies for NUMA systems, but the suffix_nodeis appended to the function
name. As compared with the UMA functions, an additional parameter is required to specify which node
is used for memory reservation.
Thesefunctionsareallfrontendsfor__alloc_bootmem, which delegates the real work to
__alloc_bootmem_nopanic. Since more than one bootmem allocator can be registered (recall
that they are all kept in a global list),__alloc_bootmem_coreiterates over all of them until one
succeeds.
On NUMA systems,__alloc_bootmem_nodeis used to implement the API functions. First, work is passed
on to__alloc_bootmem_coreto try the allocation on the specific bootmem allocator of the node. If this
fails, the function falls back to__alloc_bootmem, which tries all nodes.
mm/bootmem.c
void * __init __alloc_bootmem(unsigned long size, unsigned long align,
unsigned long goal)
__alloc_bootmemrequires three parameters to describe a request:sizeis the size of the desired memory
area,alignindicates the alignment of the data, andgoalspecifies the start address at which the search
for a suitable free area is to begin. The front ends use the function as follows:
<bootmem.h>
#define alloc_bootmem(x) \
__alloc_bootmem((x), SMP_CACHE_BYTES, __pa(MAX_DMA_ADDRESS))
#define alloc_bootmem_low(x) \
__alloc_bootmem((x), SMP_CACHE_BYTES, 0)
#define alloc_bootmem_pages(x) \
__alloc_bootmem((x), PAGE_SIZE, __pa(MAX_DMA_ADDRESS))
#define alloc_bootmem_low_pages(x) \
__alloc_bootmem((x), PAGE_SIZE, 0)