Boot time memory management¶
Early system initialization cannot use “normal” memory managementsimply because it is not set up yet. But there is still need toallocate memory for various data structures, for instance for thephysical page allocator.
A specialized allocator calledmemblock performs theboot time memory management. The architecture specific initializationmust set it up insetup_arch() and tear it down inmem_init() functions.
Once the early memory management is available it offers a variety offunctions and macros for memory allocations. The allocation requestmay be directed to the first (and probably the only) node or to aparticular node in a NUMA system. There are API variants that panicwhen an allocation fails and those that don’t.
Memblock also offers a variety of APIs that control its own behaviour.
Memblock Overview¶
Memblock is a method of managing memory regions during the earlyboot period when the usual kernel memory allocators are not up andrunning.
Memblock views the system memory as collections of contiguousregions. There are several types of these collections:
memory- describes the physical memory available to thekernel; this may differ from the actual physical memory installedin the system, for instance when the memory is restricted withmem=command line parameterreserved- describes the regions that were allocatedphysmem- describes the actual physical memory available duringboot regardless of the possible restrictions and memory hot(un)plug;thephysmemtype is only available on some architectures.
Each region is represented bystructmemblock_region thatdefines the region extents, its attributes and NUMA node id on NUMAsystems. Every memory type is described by thestructmemblock_type which contains an array of memory regions along withthe allocator metadata. The “memory” and “reserved” types are nicelywrapped withstructmemblock. This structure is staticallyinitialized at build time. The region arrays are initially sized toINIT_MEMBLOCK_REGIONS for “memory” andINIT_MEMBLOCK_RESERVED_REGIONSfor “reserved”. The region array for “physmem” is initially sized toINIT_PHYSMEM_REGIONS.The memblock_allow_resize() enables automatic resizing of the regionarrays during addition of new regions. This feature should be usedwith care so that memory allocated for the region array will notoverlap with areas that should be reserved, for example initrd.
The early architecture setup should tell memblock what the physicalmemory layout is by usingmemblock_add() ormemblock_add_node()functions. The first function does not assign the region to a NUMAnode and it is appropriate for UMA systems. Yet, it is possible touse it on NUMA systems as well and assign the region to a NUMA nodelater in the setup process usingmemblock_set_node(). Thememblock_add_node() performs such an assignment directly.
Once memblock is setup the memory can be allocated using one of theAPI variants:
- memblock_phys_alloc*() - these functions return thephysicaladdress of the allocated memory
- memblock_alloc*() - these functions return thevirtual addressof the allocated memory.
Note, that both API variants use implicit assumptions about allowedmemory ranges and the fallback methods. Consult the documentationofmemblock_alloc_internal() andmemblock_alloc_range_nid()functions for more elaborate description.
As the system boot progresses, the architecture specific mem_init()function frees all the memory to the buddy page allocator.
Unless an architecture enablesCONFIG_ARCH_KEEP_MEMBLOCK, thememblock data structures (except “physmem”) will be discarded after thesystem initialization completes.
Functions and structures¶
Here is the description of memblock data structures, functions andmacros. Some of them are actually internal, but since they aredocumented it would be silly to omit them. Besides, reading thedescriptions for the internal functions can help to understand whatreally happens under the hood.
- enum
memblock_flags¶ definition of memory region attributes
Constants
MEMBLOCK_NONE- no special request
MEMBLOCK_HOTPLUG- hotpluggable region
MEMBLOCK_MIRROR- mirrored region
MEMBLOCK_NOMAP- don’t add to kernel direct mapping
- struct
memblock_region¶ represents a memory region
Definition
struct memblock_region { phys_addr_t base; phys_addr_t size; enum memblock_flags flags;#ifdef CONFIG_NEED_MULTIPLE_NODES; int nid;#endif;};Members
base- base address of the region
size- size of the region
flags- memory region attributes
nid- NUMA node id
- struct
memblock_type¶ collection of memory regions of certain type
Definition
struct memblock_type { unsigned long cnt; unsigned long max; phys_addr_t total_size; struct memblock_region *regions; char *name;};Members
cnt- number of regions
max- size of the allocated array
total_size- size of all regions
regions- array of regions
name- the memory type symbolic name
- struct
memblock¶ memblock allocator metadata
Definition
struct memblock { bool bottom_up; phys_addr_t current_limit; struct memblock_type memory; struct memblock_type reserved;};Members
bottom_up- is bottom up direction?
current_limit- physical address of the current allocation limit
memory- usable memory regions
reserved- reserved memory regions
for_each_physmem_range(i,type,p_start,p_end)¶iterate through physmem areas not included in type.
Parameters
i- u64 used as loop variable
type- ptr to memblock_type which excludes from the iteration, can be
NULL p_start- ptr to phys_addr_t for start address of the range, can be
NULL p_end- ptr to phys_addr_t for end address of the range, can be
NULL
for_each_mem_range(i,type_a,type_b,nid,flags,p_start,p_end,p_nid)¶iterate through memblock areas from type_a and not included in type_b. Or just type_a if type_b is NULL.
Parameters
i- u64 used as loop variable
type_a- ptr to memblock_type to iterate
type_b- ptr to memblock_type which excludes from the iteration
nid- node selector,
NUMA_NO_NODEfor all nodes flags- pick from blocks based on memory attributes
p_start- ptr to phys_addr_t for start address of the range, can be
NULL p_end- ptr to phys_addr_t for end address of the range, can be
NULL p_nid- ptr to int for nid of the range, can be
NULL
for_each_mem_range_rev(i,type_a,type_b,nid,flags,p_start,p_end,p_nid)¶reverse iterate through memblock areas from type_a and not included in type_b. Or just type_a if type_b is NULL.
Parameters
i- u64 used as loop variable
type_a- ptr to memblock_type to iterate
type_b- ptr to memblock_type which excludes from the iteration
nid- node selector,
NUMA_NO_NODEfor all nodes flags- pick from blocks based on memory attributes
p_start- ptr to phys_addr_t for start address of the range, can be
NULL p_end- ptr to phys_addr_t for end address of the range, can be
NULL p_nid- ptr to int for nid of the range, can be
NULL
for_each_reserved_mem_region(i,p_start,p_end)¶iterate over all reserved memblock areas
Parameters
i- u64 used as loop variable
p_start- ptr to phys_addr_t for start address of the range, can be
NULL p_end- ptr to phys_addr_t for end address of the range, can be
NULL
Description
Walks over reserved areas of memblock. Available as soon as memblockis initialized.
for_each_mem_pfn_range(i,nid,p_start,p_end,p_nid)¶early memory pfn range iterator
Parameters
i- an integer used as loop variable
nid- node selector,
MAX_NUMNODESfor all nodes p_start- ptr to ulong for start pfn of the range, can be
NULL p_end- ptr to ulong for end pfn of the range, can be
NULL p_nid- ptr to int for nid of the range, can be
NULL
Description
Walks over configured memory ranges.
for_each_free_mem_pfn_range_in_zone(i,zone,p_start,p_end)¶iterate through zone specific free memblock areas
Parameters
i- u64 used as loop variable
zone- zone in which all of the memory blocks reside
p_start- ptr to phys_addr_t for start address of the range, can be
NULL p_end- ptr to phys_addr_t for end address of the range, can be
NULL
Description
Walks over free (memory && !reserved) areas of memblock in a specificzone. Available once memblock and an empty zone is initialized. The mainassumption is that the zone start, end, and pgdat have been associated.This way we can use the zone to determine NUMA node, and if a given partof the memblock is valid for the zone.
for_each_free_mem_pfn_range_in_zone_from(i,zone,p_start,p_end)¶iterate through zone specific free memblock areas from a given point
Parameters
i- u64 used as loop variable
zone- zone in which all of the memory blocks reside
p_start- ptr to phys_addr_t for start address of the range, can be
NULL p_end- ptr to phys_addr_t for end address of the range, can be
NULL
Description
Walks over free (memory && !reserved) areas of memblock in a specificzone, continuing from current position. Available as soon as memblock isinitialized.
for_each_free_mem_range(i,nid,flags,p_start,p_end,p_nid)¶iterate through free memblock areas
Parameters
i- u64 used as loop variable
nid- node selector,
NUMA_NO_NODEfor all nodes flags- pick from blocks based on memory attributes
p_start- ptr to phys_addr_t for start address of the range, can be
NULL p_end- ptr to phys_addr_t for end address of the range, can be
NULL p_nid- ptr to int for nid of the range, can be
NULL
Description
Walks over free (memory && !reserved) areas of memblock. Available assoon as memblock is initialized.
for_each_free_mem_range_reverse(i,nid,flags,p_start,p_end,p_nid)¶rev-iterate through free memblock areas
Parameters
i- u64 used as loop variable
nid- node selector,
NUMA_NO_NODEfor all nodes flags- pick from blocks based on memory attributes
p_start- ptr to phys_addr_t for start address of the range, can be
NULL p_end- ptr to phys_addr_t for end address of the range, can be
NULL p_nid- ptr to int for nid of the range, can be
NULL
Description
Walks over free (memory && !reserved) areas of memblock in reverseorder. Available as soon as memblock is initialized.
- void
memblock_set_current_limit(phys_addr_t limit)¶ Set the current allocation limit to allow limiting allocations to what is currently accessible during boot
Parameters
phys_addr_tlimit- New limit value (physical address)
- unsigned long
memblock_region_memory_base_pfn(const structmemblock_region * reg)¶ get the lowest pfn of the memory region
Parameters
conststructmemblock_region*reg- memblock_region structure
Return
the lowest pfn intersecting with the memory region
- unsigned long
memblock_region_memory_end_pfn(const structmemblock_region * reg)¶ get the end pfn of the memory region
Parameters
conststructmemblock_region*reg- memblock_region structure
Return
the end_pfn of the reserved region
- unsigned long
memblock_region_reserved_base_pfn(const structmemblock_region * reg)¶ get the lowest pfn of the reserved region
Parameters
conststructmemblock_region*reg- memblock_region structure
Return
the lowest pfn intersecting with the reserved region
- unsigned long
memblock_region_reserved_end_pfn(const structmemblock_region * reg)¶ get the end pfn of the reserved region
Parameters
conststructmemblock_region*reg- memblock_region structure
Return
the end_pfn of the reserved region
- phys_addr_t __init_memblock
__memblock_find_range_bottom_up(phys_addr_t start, phys_addr_t end, phys_addr_t size, phys_addr_t align, int nid, enummemblock_flags flags)¶ find free area utility in bottom-up
Parameters
phys_addr_tstart- start of candidate range
phys_addr_tend- end of candidate range, can be
MEMBLOCK_ALLOC_ANYWHEREorMEMBLOCK_ALLOC_ACCESSIBLE phys_addr_tsize- size of free area to find
phys_addr_talign- alignment of free area to find
intnid- nid of the free area to find,
NUMA_NO_NODEfor any node enummemblock_flagsflags- pick from blocks based on memory attributes
Description
Utility called frommemblock_find_in_range_node(), find free area bottom-up.
Return
Found address on success, 0 on failure.
- phys_addr_t __init_memblock
__memblock_find_range_top_down(phys_addr_t start, phys_addr_t end, phys_addr_t size, phys_addr_t align, int nid, enummemblock_flags flags)¶ find free area utility, in top-down
Parameters
phys_addr_tstart- start of candidate range
phys_addr_tend- end of candidate range, can be
MEMBLOCK_ALLOC_ANYWHEREorMEMBLOCK_ALLOC_ACCESSIBLE phys_addr_tsize- size of free area to find
phys_addr_talign- alignment of free area to find
intnid- nid of the free area to find,
NUMA_NO_NODEfor any node enummemblock_flagsflags- pick from blocks based on memory attributes
Description
Utility called frommemblock_find_in_range_node(), find free area top-down.
Return
Found address on success, 0 on failure.
- phys_addr_t __init_memblock
memblock_find_in_range_node(phys_addr_t size, phys_addr_t align, phys_addr_t start, phys_addr_t end, int nid, enummemblock_flags flags)¶ find free area in given range and node
Parameters
phys_addr_tsize- size of free area to find
phys_addr_talign- alignment of free area to find
phys_addr_tstart- start of candidate range
phys_addr_tend- end of candidate range, can be
MEMBLOCK_ALLOC_ANYWHEREorMEMBLOCK_ALLOC_ACCESSIBLE intnid- nid of the free area to find,
NUMA_NO_NODEfor any node enummemblock_flagsflags- pick from blocks based on memory attributes
Description
Findsize free area aligned toalign in the specified range and node.
When allocation direction is bottom-up, thestart should be greaterthan the end of the kernel image. Otherwise, it will be trimmed. Thereason is that we want the bottom-up allocation just near the kernelimage so it is highly likely that the allocated memory and the kernelwill reside in the same node.
If bottom-up allocation failed, will try to allocate memory top-down.
Return
Found address on success, 0 on failure.
- phys_addr_t __init_memblock
memblock_find_in_range(phys_addr_t start, phys_addr_t end, phys_addr_t size, phys_addr_t align)¶ find free area in given range
Parameters
phys_addr_tstart- start of candidate range
phys_addr_tend- end of candidate range, can be
MEMBLOCK_ALLOC_ANYWHEREorMEMBLOCK_ALLOC_ACCESSIBLE phys_addr_tsize- size of free area to find
phys_addr_talign- alignment of free area to find
Description
Findsize free area aligned toalign in the specified range.
Return
Found address on success, 0 on failure.
- void
memblock_discard(void)¶ discard memory and reserved arrays if they were allocated
Parameters
void- no arguments
- int __init_memblock
memblock_double_array(structmemblock_type * type, phys_addr_t new_area_start, phys_addr_t new_area_size)¶ double the size of the memblock regions array
Parameters
structmemblock_type*type- memblock type of the regions array being doubled
phys_addr_tnew_area_start- starting address of memory range to avoid overlap with
phys_addr_tnew_area_size- size of memory range to avoid overlap with
Description
Double the size of thetype regions array. If memblock is being used toallocate memory for a new reserved regions array and there is a previouslyallocated memory range [new_area_start,new_area_start +new_area_size]waiting to be reserved, ensure the memory used by the new array doesnot overlap.
Return
0 on success, -1 on failure.
- void __init_memblock
memblock_merge_regions(structmemblock_type * type)¶ merge neighboring compatible regions
Parameters
structmemblock_type*type- memblock type to scan
Description
Scantype and merge neighboring compatible regions.
- void __init_memblock
memblock_insert_region(structmemblock_type * type, int idx, phys_addr_t base, phys_addr_t size, int nid, enummemblock_flags flags)¶ insert new memblock region
Parameters
structmemblock_type*type- memblock type to insert into
intidx- index for the insertion point
phys_addr_tbase- base address of the new region
phys_addr_tsize- size of the new region
intnid- node id of the new region
enummemblock_flagsflags- flags of the new region
Description
Insert new memblock region [base,base +size) intotype atidx.type must already have extra room to accommodate the new region.
- int __init_memblock
memblock_add_range(structmemblock_type * type, phys_addr_t base, phys_addr_t size, int nid, enummemblock_flags flags)¶ add new memblock region
Parameters
structmemblock_type*type- memblock type to add new region into
phys_addr_tbase- base address of the new region
phys_addr_tsize- size of the new region
intnid- nid of the new region
enummemblock_flagsflags- flags of the new region
Description
Add new memblock region [base,base +size) intotype. The new regionis allowed to overlap with existing ones - overlaps don’t affect alreadyexisting regions.type is guaranteed to be minimal (all neighbouringcompatible regions are merged) after the addition.
Return
0 on success, -errno on failure.
- int __init_memblock
memblock_add_node(phys_addr_t base, phys_addr_t size, int nid)¶ add new memblock region within a NUMA node
Parameters
phys_addr_tbase- base address of the new region
phys_addr_tsize- size of the new region
intnid- nid of the new region
Description
Add new memblock region [base,base +size) to the “memory”type. Seememblock_add_range() description for mode details
Return
0 on success, -errno on failure.
- int __init_memblock
memblock_add(phys_addr_t base, phys_addr_t size)¶ add new memblock region
Parameters
phys_addr_tbase- base address of the new region
phys_addr_tsize- size of the new region
Description
Add new memblock region [base,base +size) to the “memory”type. Seememblock_add_range() description for mode details
Return
0 on success, -errno on failure.
- int __init_memblock
memblock_isolate_range(structmemblock_type * type, phys_addr_t base, phys_addr_t size, int * start_rgn, int * end_rgn)¶ isolate given range into disjoint memblocks
Parameters
structmemblock_type*type- memblock type to isolate range for
phys_addr_tbase- base of range to isolate
phys_addr_tsize- size of range to isolate
int*start_rgn- out parameter for the start of isolated region
int*end_rgn- out parameter for the end of isolated region
Description
Walktype and ensure that regions don’t cross the boundaries defined by[base,base +size). Crossing regions are split at the boundaries,which may create at most two more regions. The index of the firstregion inside the range is returned in*start_rgn and end in*end_rgn.
Return
0 on success, -errno on failure.
- int __init_memblock
memblock_free(phys_addr_t base, phys_addr_t size)¶ free boot memory block
Parameters
phys_addr_tbase- phys starting address of the boot memory block
phys_addr_tsize- size of the boot memory block in bytes
Description
Free boot memory block previously allocated by memblock_alloc_xx() API.The freeing memory will not be released to the buddy allocator.
- int __init_memblock
memblock_setclr_flag(phys_addr_t base, phys_addr_t size, int set, int flag)¶ set or clear flag for a memory region
Parameters
phys_addr_tbase- base address of the region
phys_addr_tsize- size of the region
intset- set or clear the flag
intflag- the flag to udpate
Description
This function isolates region [base,base +size), and sets/clears flag
Return
0 on success, -errno on failure.
- int __init_memblock
memblock_mark_hotplug(phys_addr_t base, phys_addr_t size)¶ Mark hotpluggable memory with flag MEMBLOCK_HOTPLUG.
Parameters
phys_addr_tbase- the base phys addr of the region
phys_addr_tsize- the size of the region
Return
0 on success, -errno on failure.
- int __init_memblock
memblock_clear_hotplug(phys_addr_t base, phys_addr_t size)¶ Clear flag MEMBLOCK_HOTPLUG for a specified region.
Parameters
phys_addr_tbase- the base phys addr of the region
phys_addr_tsize- the size of the region
Return
0 on success, -errno on failure.
- int __init_memblock
memblock_mark_mirror(phys_addr_t base, phys_addr_t size)¶ Mark mirrored memory with flag MEMBLOCK_MIRROR.
Parameters
phys_addr_tbase- the base phys addr of the region
phys_addr_tsize- the size of the region
Return
0 on success, -errno on failure.
- int __init_memblock
memblock_mark_nomap(phys_addr_t base, phys_addr_t size)¶ Mark a memory region with flag MEMBLOCK_NOMAP.
Parameters
phys_addr_tbase- the base phys addr of the region
phys_addr_tsize- the size of the region
Return
0 on success, -errno on failure.
- int __init_memblock
memblock_clear_nomap(phys_addr_t base, phys_addr_t size)¶ Clear flag MEMBLOCK_NOMAP for a specified region.
Parameters
phys_addr_tbase- the base phys addr of the region
phys_addr_tsize- the size of the region
Return
0 on success, -errno on failure.
- void __init_memblock
__next_reserved_mem_region(u64 * idx, phys_addr_t * out_start, phys_addr_t * out_end)¶ next function for for_each_reserved_region()
Parameters
u64*idx- pointer to u64 loop variable
phys_addr_t*out_start- ptr to phys_addr_t for start address of the region, can be
NULL phys_addr_t*out_end- ptr to phys_addr_t for end address of the region, can be
NULL
Description
Iterate over all reserved memory regions.
- void
__next_mem_range(u64 * idx, int nid, enummemblock_flags flags, structmemblock_type * type_a, structmemblock_type * type_b, phys_addr_t * out_start, phys_addr_t * out_end, int * out_nid)¶ next function for
for_each_free_mem_range()etc.
Parameters
u64*idx- pointer to u64 loop variable
intnid- node selector,
NUMA_NO_NODEfor all nodes enummemblock_flagsflags- pick from blocks based on memory attributes
structmemblock_type*type_a- pointer to memblock_type from where the range is taken
structmemblock_type*type_b- pointer to memblock_type which excludes memory from being taken
phys_addr_t*out_start- ptr to phys_addr_t for start address of the range, can be
NULL phys_addr_t*out_end- ptr to phys_addr_t for end address of the range, can be
NULL int*out_nid- ptr to int for nid of the range, can be
NULL
Description
Find the first area from*idx which matchesnid, fill the outparameters, and update*idx for the next iteration. The lower 32bit of*idx contains index into type_a and the upper 32bit indexes theareas before each region in type_b. For example, if type_b regionslook like the following,
0:[0-16), 1:[32-48), 2:[128-130)
The upper 32bit indexes the following regions.
0:[0-0), 1:[16-32), 2:[48-128), 3:[130-MAX)
As both region arrays are sorted, the function advances the two indicesin lockstep and returns each intersection.
- void __init_memblock
__next_mem_range_rev(u64 * idx, int nid, enummemblock_flags flags, structmemblock_type * type_a, structmemblock_type * type_b, phys_addr_t * out_start, phys_addr_t * out_end, int * out_nid)¶ generic next function for for_each_*_range_rev()
Parameters
u64*idx- pointer to u64 loop variable
intnid- node selector,
NUMA_NO_NODEfor all nodes enummemblock_flagsflags- pick from blocks based on memory attributes
structmemblock_type*type_a- pointer to memblock_type from where the range is taken
structmemblock_type*type_b- pointer to memblock_type which excludes memory from being taken
phys_addr_t*out_start- ptr to phys_addr_t for start address of the range, can be
NULL phys_addr_t*out_end- ptr to phys_addr_t for end address of the range, can be
NULL int*out_nid- ptr to int for nid of the range, can be
NULL
Description
Finds the next range from type_a which is not marked as unsuitablein type_b.
Reverse of__next_mem_range().
- int __init_memblock
memblock_set_node(phys_addr_t base, phys_addr_t size, structmemblock_type * type, int nid)¶ set node ID on memblock regions
Parameters
phys_addr_tbase- base of area to set node ID for
phys_addr_tsize- size of area to set node ID for
structmemblock_type*type- memblock type to set node ID for
intnid- node ID to set
Description
Set the nid of memblocktype regions in [base,base +size) tonid.Regions which cross the area boundaries are split as necessary.
Return
0 on success, -errno on failure.
- void __init_memblock
__next_mem_pfn_range_in_zone(u64 * idx, struct zone * zone, unsigned long * out_spfn, unsigned long * out_epfn)¶ iterator for for_each_*_range_in_zone()
Parameters
u64*idx- pointer to u64 loop variable
structzone*zone- zone in which all of the memory blocks reside
unsignedlong*out_spfn- ptr to ulong for start pfn of the range, can be
NULL unsignedlong*out_epfn- ptr to ulong for end pfn of the range, can be
NULL
Description
This function is meant to be a zone/pfn specific wrapper for thefor_each_mem_range type iterators. Specifically they are used in thedeferred memory init routines and as such we were duplicating much ofthis logic throughout the code. So instead of having it in multiplelocations it seemed like it would make more sense to centralize this toone new iterator that does everything they need.
- phys_addr_t
memblock_alloc_range_nid(phys_addr_t size, phys_addr_t align, phys_addr_t start, phys_addr_t end, int nid, bool exact_nid)¶ allocate boot memory block
Parameters
phys_addr_tsize- size of memory block to be allocated in bytes
phys_addr_talign- alignment of the region and block’s size
phys_addr_tstart- the lower bound of the memory region to allocate (phys address)
phys_addr_tend- the upper bound of the memory region to allocate (phys address)
intnid- nid of the free area to find,
NUMA_NO_NODEfor any node boolexact_nid- control the allocation fall back to other nodes
Description
The allocation is performed from memory region limited bymemblock.current_limit ifend ==MEMBLOCK_ALLOC_ACCESSIBLE.
If the specified node can not hold the requested memory andexact_nidis false, the allocation falls back to any node in the system.
For systems with memory mirroring, the allocation is attempted firstfrom the regions with mirroring enabled and then retried from anymemory region.
In addition, function sets the min_count to 0 using kmemleak_alloc_phys forallocated boot memory block, so that it is never reported as leaks.
Return
Physical address of allocated memory block on success,0 on failure.
- phys_addr_t
memblock_phys_alloc_range(phys_addr_t size, phys_addr_t align, phys_addr_t start, phys_addr_t end)¶ allocate a memory block inside specified range
Parameters
phys_addr_tsize- size of memory block to be allocated in bytes
phys_addr_talign- alignment of the region and block’s size
phys_addr_tstart- the lower bound of the memory region to allocate (physical address)
phys_addr_tend- the upper bound of the memory region to allocate (physical address)
Description
Allocatesize bytes in the betweenstart andend.
Return
physical address of the allocated memory block on success,0 on failure.
- phys_addr_t
memblock_phys_alloc_try_nid(phys_addr_t size, phys_addr_t align, int nid)¶ allocate a memory block from specified MUMA node
Parameters
phys_addr_tsize- size of memory block to be allocated in bytes
phys_addr_talign- alignment of the region and block’s size
intnid- nid of the free area to find,
NUMA_NO_NODEfor any node
Description
Allocates memory block from the specified NUMA node. If the nodehas no available memory, attempts to allocated from any node in thesystem.
Return
physical address of the allocated memory block on success,0 on failure.
- void *
memblock_alloc_internal(phys_addr_t size, phys_addr_t align, phys_addr_t min_addr, phys_addr_t max_addr, int nid, bool exact_nid)¶ allocate boot memory block
Parameters
phys_addr_tsize- size of memory block to be allocated in bytes
phys_addr_talign- alignment of the region and block’s size
phys_addr_tmin_addr- the lower bound of the memory region to allocate (phys address)
phys_addr_tmax_addr- the upper bound of the memory region to allocate (phys address)
intnid- nid of the free area to find,
NUMA_NO_NODEfor any node boolexact_nid- control the allocation fall back to other nodes
Description
Allocates memory block usingmemblock_alloc_range_nid() andconverts the returned physical address to virtual.
Themin_addr limit is dropped if it can not be satisfied and the allocationwill fall back to memory belowmin_addr. Other constraints, suchas node and mirrored memory will be handled again inmemblock_alloc_range_nid().
Return
Virtual address of allocated memory block on success, NULL on failure.
- void *
memblock_alloc_exact_nid_raw(phys_addr_t size, phys_addr_t align, phys_addr_t min_addr, phys_addr_t max_addr, int nid)¶ allocate boot memory block on the exact node without zeroing memory
Parameters
phys_addr_tsize- size of memory block to be allocated in bytes
phys_addr_talign- alignment of the region and block’s size
phys_addr_tmin_addr- the lower bound of the memory region from where the allocationis preferred (phys address)
phys_addr_tmax_addr- the upper bound of the memory region from where the allocationis preferred (phys address), or
MEMBLOCK_ALLOC_ACCESSIBLEtoallocate only from memory limited by memblock.current_limit value intnid- nid of the free area to find,
NUMA_NO_NODEfor any node
Description
Public function, provides additional debug information (including callerinfo), if enabled. Does not zero allocated memory.
Return
Virtual address of allocated memory block on success, NULL on failure.
- void *
memblock_alloc_try_nid_raw(phys_addr_t size, phys_addr_t align, phys_addr_t min_addr, phys_addr_t max_addr, int nid)¶ allocate boot memory block without zeroing memory and without panicking
Parameters
phys_addr_tsize- size of memory block to be allocated in bytes
phys_addr_talign- alignment of the region and block’s size
phys_addr_tmin_addr- the lower bound of the memory region from where the allocationis preferred (phys address)
phys_addr_tmax_addr- the upper bound of the memory region from where the allocationis preferred (phys address), or
MEMBLOCK_ALLOC_ACCESSIBLEtoallocate only from memory limited by memblock.current_limit value intnid- nid of the free area to find,
NUMA_NO_NODEfor any node
Description
Public function, provides additional debug information (including callerinfo), if enabled. Does not zero allocated memory, does not panic if requestcannot be satisfied.
Return
Virtual address of allocated memory block on success, NULL on failure.
- void *
memblock_alloc_try_nid(phys_addr_t size, phys_addr_t align, phys_addr_t min_addr, phys_addr_t max_addr, int nid)¶ allocate boot memory block
Parameters
phys_addr_tsize- size of memory block to be allocated in bytes
phys_addr_talign- alignment of the region and block’s size
phys_addr_tmin_addr- the lower bound of the memory region from where the allocationis preferred (phys address)
phys_addr_tmax_addr- the upper bound of the memory region from where the allocationis preferred (phys address), or
MEMBLOCK_ALLOC_ACCESSIBLEtoallocate only from memory limited by memblock.current_limit value intnid- nid of the free area to find,
NUMA_NO_NODEfor any node
Description
Public function, provides additional debug information (including callerinfo), if enabled. This function zeroes the allocated memory.
Return
Virtual address of allocated memory block on success, NULL on failure.
- void
__memblock_free_late(phys_addr_t base, phys_addr_t size)¶ free pages directly to buddy allocator
Parameters
phys_addr_tbase- phys starting address of the boot memory block
phys_addr_tsize- size of the boot memory block in bytes
Description
This is only useful when the memblock allocator has already been torndown, but we are still initializing the system. Pages are released directlyto the buddy allocator.
- bool __init_memblock
memblock_is_region_memory(phys_addr_t base, phys_addr_t size)¶ check if a region is a subset of memory
Parameters
phys_addr_tbase- base of region to check
phys_addr_tsize- size of region to check
Description
Check if the region [base,base +size) is a subset of a memory block.
Return
0 if false, non-zero if true
- bool __init_memblock
memblock_is_region_reserved(phys_addr_t base, phys_addr_t size)¶ check if a region intersects reserved memory
Parameters
phys_addr_tbase- base of region to check
phys_addr_tsize- size of region to check
Description
Check if the region [base,base +size) intersects a reservedmemory block.
Return
True if they intersect, false if not.
- unsigned long
memblock_free_all(void)¶ release free pages to the buddy allocator
Parameters
void- no arguments
Return
the number of pages actually released.