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 parameter

  • reserved - describes the regions that were allocated

  • physmem - describes the actual physical memory available duringboot regardless of the possible restrictions and memory hot(un)plug;thephysmem type 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_typewhich 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_MEMORY_REGIONS for “memory” andINIT_MEMBLOCK_RESERVED_REGIONS for “reserved”. The region arrayfor “physmem” is initially sized toINIT_PHYSMEM_REGIONS.Thememblock_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 specificmem_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.

enummemblock_flags

definition of memory region attributes

Constants

MEMBLOCK_NONE

no special request

MEMBLOCK_HOTPLUG

memory region indicated in the firmware-provided memorymap during early boot as hot(un)pluggable system RAM (e.g., memory rangethat might get hotunplugged later). With “movable_node” set on the kernelcommandline, try keeping this memory region hotunpluggable. Does not applyto memblocks added (“hotplugged”) after early boot.

MEMBLOCK_MIRROR

mirrored region

MEMBLOCK_NOMAP

don’t add to kernel direct mapping and treat asreserved in the memory map; refer tomemblock_mark_nomap() descriptionfor further details

MEMBLOCK_DRIVER_MANAGED

memory region that is always detected and addedvia a driver, and never indicated in the firmware-provided memory map assystem RAM. This corresponds to IORESOURCE_SYSRAM_DRIVER_MANAGED in thekernel resource tree.

MEMBLOCK_RSRV_NOINIT

reserved memory region for whichstructpages are notfully initialized. Users of this flag are responsible to properly initializestructpages of this region

MEMBLOCK_RSRV_KERN

memory region that is reserved for kernel use,either explictitly withmemblock_reserve_kern() or via memblockallocation APIs. All memblock allocations set this flag.

MEMBLOCK_KHO_SCRATCH

memory region that kexec can pass to the nextkernel in handover mode. During early boot, we do not know about allmemory reservations yet, so we get scratch memory from the previouskernel that we know is good to use. It is the only memory thatallocations may happen from in this phase.

structmemblock_region

represents a memory region

Definition:

struct memblock_region {    phys_addr_t base;    phys_addr_t size;    enum memblock_flags flags;#ifdef CONFIG_NUMA;    int nid;#endif;};

Members

base

base address of the region

size

size of the region

flags

memory region attributes

nid

NUMA node id

structmemblock_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

structmemblock

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

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 beNULL

p_start

ptr to phys_addr_t for start address of the range, can beNULL

p_end

ptr to phys_addr_t for end address of the range, can beNULL

__for_each_mem_range

__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_NODE for all nodes

flags

pick from blocks based on memory attributes

p_start

ptr to phys_addr_t for start address of the range, can beNULL

p_end

ptr to phys_addr_t for end address of the range, can beNULL

p_nid

ptr to int for nid of the range, can beNULL

__for_each_mem_range_rev

__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_NODE for all nodes

flags

pick from blocks based on memory attributes

p_start

ptr to phys_addr_t for start address of the range, can beNULL

p_end

ptr to phys_addr_t for end address of the range, can beNULL

p_nid

ptr to int for nid of the range, can beNULL

for_each_mem_range

for_each_mem_range(i,p_start,p_end)

iterate through memory areas.

Parameters

i

u64 used as loop variable

p_start

ptr to phys_addr_t for start address of the range, can beNULL

p_end

ptr to phys_addr_t for end address of the range, can beNULL

for_each_mem_range_rev

for_each_mem_range_rev(i,p_start,p_end)

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

p_start

ptr to phys_addr_t for start address of the range, can beNULL

p_end

ptr to phys_addr_t for end address of the range, can beNULL

for_each_reserved_mem_range

for_each_reserved_mem_range(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 beNULL

p_end

ptr to phys_addr_t for end address of the range, can beNULL

Description

Walks over reserved areas of memblock. Available as soon as memblockis initialized.

for_each_mem_pfn_range

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_NUMNODES for all nodes

p_start

ptr to ulong for start pfn of the range, can beNULL

p_end

ptr to ulong for end pfn of the range, can beNULL

p_nid

ptr to int for nid of the range, can beNULL

Description

Walks over configured memory ranges.

for_each_free_mem_range

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_NODE for all nodes

flags

pick from blocks based on memory attributes

p_start

ptr to phys_addr_t for start address of the range, can beNULL

p_end

ptr to phys_addr_t for end address of the range, can beNULL

p_nid

ptr to int for nid of the range, can beNULL

Description

Walks over free (memory && !reserved) areas of memblock. Available assoon as memblock is initialized.

for_each_free_mem_range_reverse

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_NODE for all nodes

flags

pick from blocks based on memory attributes

p_start

ptr to phys_addr_t for start address of the range, can beNULL

p_end

ptr to phys_addr_t for end address of the range, can beNULL

p_nid

ptr to int for nid of the range, can beNULL

Description

Walks over free (memory && !reserved) areas of memblock in reverseorder. Available as soon as memblock is initialized.

voidmemblock_set_current_limit(phys_addr_tlimit)

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)

unsignedlongmemblock_region_memory_base_pfn(conststructmemblock_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

unsignedlongmemblock_region_memory_end_pfn(conststructmemblock_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

unsignedlongmemblock_region_reserved_base_pfn(conststructmemblock_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

unsignedlongmemblock_region_reserved_end_pfn(conststructmemblock_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

for_each_mem_region

for_each_mem_region(region)

iterate over memory regions

Parameters

region

loop variable

for_each_reserved_mem_region

for_each_reserved_mem_region(region)

itereate over reserved memory regions

Parameters

region

loop variable

phys_addr_t__init_memblock__memblock_find_range_bottom_up(phys_addr_tstart,phys_addr_tend,phys_addr_tsize,phys_addr_talign,intnid,enummemblock_flagsflags)

find free area utility in bottom-up

Parameters

phys_addr_tstart

start of candidate range

phys_addr_tend

end of candidate range, can beMEMBLOCK_ALLOC_ANYWHERE orMEMBLOCK_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_NODE for 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_tstart,phys_addr_tend,phys_addr_tsize,phys_addr_talign,intnid,enummemblock_flagsflags)

find free area utility, in top-down

Parameters

phys_addr_tstart

start of candidate range

phys_addr_tend

end of candidate range, can beMEMBLOCK_ALLOC_ANYWHERE orMEMBLOCK_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_NODE for 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_memblockmemblock_find_in_range_node(phys_addr_tsize,phys_addr_talign,phys_addr_tstart,phys_addr_tend,intnid,enummemblock_flagsflags)

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 beMEMBLOCK_ALLOC_ANYWHERE orMEMBLOCK_ALLOC_ACCESSIBLE

intnid

nid of the free area to find,NUMA_NO_NODE for any node

enummemblock_flagsflags

pick from blocks based on memory attributes

Description

Findsize free area aligned toalign in the specified range and node.

Return

Found address on success, 0 on failure.

phys_addr_t__init_memblockmemblock_find_in_range(phys_addr_tstart,phys_addr_tend,phys_addr_tsize,phys_addr_talign)

find free area in given range

Parameters

phys_addr_tstart

start of candidate range

phys_addr_tend

end of candidate range, can beMEMBLOCK_ALLOC_ANYWHERE orMEMBLOCK_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.

voidmemblock_discard(void)

discard memory and reserved arrays if they were allocated

Parameters

void

no arguments

int__init_memblockmemblock_double_array(structmemblock_type*type,phys_addr_tnew_area_start,phys_addr_tnew_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_memblockmemblock_merge_regions(structmemblock_type*type,unsignedlongstart_rgn,unsignedlongend_rgn)

merge neighboring compatible regions

Parameters

structmemblock_type*type

memblock type to scan

unsignedlongstart_rgn

start scanning from (start_rgn - 1)

unsignedlongend_rgn

end scanning at (end_rgn - 1)Scantype and merge neighboring compatible regions in [start_rgn - 1,end_rgn)

void__init_memblockmemblock_insert_region(structmemblock_type*type,intidx,phys_addr_tbase,phys_addr_tsize,intnid,enummemblock_flagsflags)

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_memblockmemblock_add_range(structmemblock_type*type,phys_addr_tbase,phys_addr_tsize,intnid,enummemblock_flagsflags)

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_memblockmemblock_add_node(phys_addr_tbase,phys_addr_tsize,intnid,enummemblock_flagsflags)

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

enummemblock_flagsflags

flags 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_memblockmemblock_add(phys_addr_tbase,phys_addr_tsize)

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.

bool__init_memblockmemblock_validate_numa_coverage(unsignedlongthreshold_bytes)

check if amount of memory with no node ID assigned is less than a threshold

Parameters

unsignedlongthreshold_bytes

maximal memory size that can have unassigned nodeID (in bytes).

Description

A buggy firmware may report memory that does not belong to any node.Check if amount of such memory is belowthreshold_bytes.

Return

true on success, false on failure.

int__init_memblockmemblock_isolate_range(structmemblock_type*type,phys_addr_tbase,phys_addr_tsize,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 the index of thefirst region after the range is returned in*end_rgn.

Return

0 on success, -errno on failure.

void__init_memblockmemblock_free(void*ptr,size_tsize)

free boot memory allocation

Parameters

void*ptr

starting address of the boot memory allocation

size_tsize

size of the boot memory block in bytes

Description

Free boot memory block previously allocated bymemblock_alloc_xx() API.The freeing memory will not be released to the buddy allocator.

int__init_memblockmemblock_phys_free(phys_addr_tbase,phys_addr_tsize)

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 bymemblock_phys_alloc_xx() API.The freeing memory will not be released to the buddy allocator.

int__init_memblockmemblock_setclr_flag(structmemblock_type*type,phys_addr_tbase,phys_addr_tsize,intset,intflag)

set or clear flag for a memory region

Parameters

structmemblock_type*type

memblock type to set/clear flag for

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 update

Description

This function isolates region [base,base +size), and sets/clears flag

Return

0 on success, -errno on failure.

int__init_memblockmemblock_mark_hotplug(phys_addr_tbase,phys_addr_tsize)

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_memblockmemblock_clear_hotplug(phys_addr_tbase,phys_addr_tsize)

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_memblockmemblock_mark_mirror(phys_addr_tbase,phys_addr_tsize)

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_memblockmemblock_mark_nomap(phys_addr_tbase,phys_addr_tsize)

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

Description

The memory regions marked withMEMBLOCK_NOMAP will not be added to thedirect mapping of the physical memory. These regions will still becovered by the memory map. Thestructpage representing NOMAP memoryframes in the memory map will bePageReserved()

Note

if the memory being markedMEMBLOCK_NOMAP was allocated frommemblock, the caller must inform kmemleak to ignore that memory

Return

0 on success, -errno on failure.

int__init_memblockmemblock_clear_nomap(phys_addr_tbase,phys_addr_tsize)

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.

int__init_memblockmemblock_reserved_mark_noinit(phys_addr_tbase,phys_addr_tsize)

Mark a reserved memory region with flag MEMBLOCK_RSRV_NOINIT

Parameters

phys_addr_tbase

the base phys addr of the region

phys_addr_tsize

the size of the region

Description

Thestructpages for the reserved regions markedMEMBLOCK_RSRV_NOINIT willnot be fully initialized to allow the caller optimize their initialization.

WhenCONFIG_DEFERRED_STRUCT_PAGE_INIT is enabled, setting this flagcompletely bypasses the initialization ofstructpages for such region.

WhenCONFIG_DEFERRED_STRUCT_PAGE_INIT is disabled,structpages in thisregion will be initialized with default values but won’t be marked asreserved.

Return

0 on success, -errno on failure.

intmemblock_mark_kho_scratch(phys_addr_tbase,phys_addr_tsize)

Mark a memory region as MEMBLOCK_KHO_SCRATCH.

Parameters

phys_addr_tbase

the base phys addr of the region

phys_addr_tsize

the size of the region

Description

Only memory regions marked withMEMBLOCK_KHO_SCRATCH will be consideredfor allocations during early boot with kexec handover.

Return

0 on success, -errno on failure.

intmemblock_clear_kho_scratch(phys_addr_tbase,phys_addr_tsize)

Clear MEMBLOCK_KHO_SCRATCH flag 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__next_mem_range(u64*idx,intnid,enummemblock_flagsflags,structmemblock_type*type_a,structmemblock_type*type_b,phys_addr_t*out_start,phys_addr_t*out_end,int*out_nid)

next function forfor_each_free_mem_range() etc.

Parameters

u64*idx

pointer to u64 loop variable

intnid

node selector,NUMA_NO_NODE for 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 beNULL

phys_addr_t*out_end

ptr to phys_addr_t for end address of the range, can beNULL

int*out_nid

ptr to int for nid of the range, can beNULL

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,intnid,enummemblock_flagsflags,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_NODE for 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 beNULL

phys_addr_t*out_end

ptr to phys_addr_t for end address of the range, can beNULL

int*out_nid

ptr to int for nid of the range, can beNULL

Description

Finds the next range from type_a which is not marked as unsuitablein type_b.

Reverse of__next_mem_range().

int__init_memblockmemblock_set_node(phys_addr_tbase,phys_addr_tsize,structmemblock_type*type,intnid)

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.

phys_addr_tmemblock_alloc_range_nid(phys_addr_tsize,phys_addr_talign,phys_addr_tstart,phys_addr_tend,intnid,boolexact_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_NODE for 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 using kmemleak_alloc_phys for allocated bootmemory block, it is never reported as leaks.

Return

Physical address of allocated memory block on success,0 on failure.

phys_addr_tmemblock_phys_alloc_range(phys_addr_tsize,phys_addr_talign,phys_addr_tstart,phys_addr_tend)

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_tmemblock_phys_alloc_try_nid(phys_addr_tsize,phys_addr_talign,intnid)

allocate a memory block from specified NUMA 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_NODE for 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_tsize,phys_addr_talign,phys_addr_tmin_addr,phys_addr_tmax_addr,intnid,boolexact_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_NODE for 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_tsize,phys_addr_talign,phys_addr_tmin_addr,phys_addr_tmax_addr,intnid)

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), orMEMBLOCK_ALLOC_ACCESSIBLE toallocate only from memory limited by memblock.current_limit value

intnid

nid of the free area to find,NUMA_NO_NODE for 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_tsize,phys_addr_talign,phys_addr_tmin_addr,phys_addr_tmax_addr,intnid)

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), orMEMBLOCK_ALLOC_ACCESSIBLE toallocate only from memory limited by memblock.current_limit value

intnid

nid of the free area to find,NUMA_NO_NODE for 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_tsize,phys_addr_talign,phys_addr_tmin_addr,phys_addr_tmax_addr,intnid)

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), orMEMBLOCK_ALLOC_ACCESSIBLE toallocate only from memory limited by memblock.current_limit value

intnid

nid of the free area to find,NUMA_NO_NODE for 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_alloc_or_panic(phys_addr_tsize,phys_addr_talign,constchar*func)

Try to allocate memory and panic on failure

Parameters

phys_addr_tsize

size of memory block to be allocated in bytes

phys_addr_talign

alignment of the region and block’s size

constchar*func

caller func name

Description

This function attempts to allocate memory using memblock_alloc,and in case of failure, it calls panic with the formatted message.This function should not be used directly, please use the macro memblock_alloc_or_panic.

voidmemblock_free_late(phys_addr_tbase,phys_addr_tsize)

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.

unsignedlongmemblock_estimated_nr_free_pages(void)

return estimated number of free pages from memblock point of view

Parameters

void

no arguments

Description

During bootup, subsystems might need a rough estimate of the number of freepages in the whole system, before precise numbers are available from thebuddy. Especially with CONFIG_DEFERRED_STRUCT_PAGE_INIT, the numbersobtained from the buddy might be very imprecise during bootup.

Return

An estimated number of free pages from memblock point of view.

bool__init_memblockmemblock_is_region_memory(phys_addr_tbase,phys_addr_tsize)

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_memblockmemblock_is_region_reserved(phys_addr_tbase,phys_addr_tsize)

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.

voidmemblock_free_all(void)

release free pages to the buddy allocator

Parameters

void

no arguments

intreserve_mem_find_by_name(constchar*name,phys_addr_t*start,phys_addr_t*size)

Find reserved memory region with a given name

Parameters

constchar*name

The name that is attached to a reserved memory region

phys_addr_t*start

If found, holds the start address

phys_addr_t*size

If found, holds the size of the address.

Description

start andsize are only updated ifname is found.

Return

1 if found or 0 if not found.

intreserve_mem_release_by_name(constchar*name)

Release reserved memory region with a given name

Parameters

constchar*name

The name that is attatched to a reserved memory region

Description

Forcibly release the pages in the reserved memory region so that those memorycan be used as free memory. After released the reserved region size becomes 0.

Return

1 if released or 0 if not found.