class Pool
Defined at line 53 of file ../../zircon/kernel/phys/lib/memalloc/include/lib/memalloc/pool.h
Pool is a container that tracks ranges of physical memory and allocates
available regions of RAM from among them.
One initializes a Pool with a variable number of arrays of memory ranges.
Except among allocated types (see Type documentation), the ranges are
permitted to overlap with one another to an arbitrary degree. In practice,
the main array of ranges would be supplied by a ZBI or synthesized from a
legacy booting protocol, while the others would consist of other auxiliary
reserved areas known to be in use at the time of initialization
(e.g., physboot's load image and the data ZBI itself). Despite arbitrarily
overlapping inputs, Pool gives normalized outputs: iteration yields ranges
that are lexicographically ordered, mutually disjoint, and for which
addr + size does not overflow.
kReserved ranges merely exist for the convenience of bootloaders: they
represent holes to be punched out of kFreeRam ranges during normalization
and do not have intrinsic value in and of themselves. Accordingly, Pool does
not explicitly track them after initialization.
Pool dynamically uses ranges of the free RAM it encodes for bookkeeping
space. On initialization, it will attempt to find initial chunks to cover
space to track the first crop of normalized ranges. With further allocation,
fragmentation will increase and Pool will internally allocate more such
space to manage it. Bookkeeping memory will also avoid the zero(th) page.
Pool is neither copyable nor movable.
Public Members
static const uint64_t kBookkeepingChunkSize
static const uint64_t kDefaultMinAddr
static const uint64_t kDefaultMaxAddr
Public Methods
void Pool ()
Default-construction uses the identity mapping for a
BookkeepingAddressToPointer.
Defined at line 113 of file ../../zircon/kernel/phys/lib/memalloc/include/lib/memalloc/pool.h
void Pool (const Pool & )
Defined at line 115 of file ../../zircon/kernel/phys/lib/memalloc/include/lib/memalloc/pool.h
void Pool (Pool && )
Defined at line 116 of file ../../zircon/kernel/phys/lib/memalloc/include/lib/memalloc/pool.h
void Pool (BookkeepingAddressToPointer bookkeeping_pointer)
Defined at line 118 of file ../../zircon/kernel/phys/lib/memalloc/include/lib/memalloc/pool.h
void Pool (BookkeepingAddressToPointer bookkeeping_pointer)
Defined at line 118 of file ../../zircon/kernel/phys/lib/memalloc/include/lib/memalloc/pool.h
void Pool (BookkeepingAddressToPointer bookkeeping_pointer)
Defined at line 118 of file ../../zircon/kernel/phys/lib/memalloc/include/lib/memalloc/pool.h
void Pool (BookkeepingAddressToPointer bookkeeping_pointer)
Defined at line 118 of file ../../zircon/kernel/phys/lib/memalloc/include/lib/memalloc/pool.h
void ~Pool ()
Defined at line 121 of file ../../zircon/kernel/phys/lib/memalloc/include/lib/memalloc/pool.h
Pool & operator= (const Pool & )
Defined at line 126 of file ../../zircon/kernel/phys/lib/memalloc/include/lib/memalloc/pool.h
Pool & operator= (Pool && )
Defined at line 127 of file ../../zircon/kernel/phys/lib/memalloc/include/lib/memalloc/pool.h
template <size_t N>
fit::result<fit::failed> Init (std::array<std::span<Range>, N> ranges, uint64_t default_min_addr, uint64_t default_max_addr)
Initializes a Pool from a variable number of memory ranges, performing an
internal allocation for its internal bookkeeping among the free RAM
encoded in the provided ranges. `default_min_addr` and `default_max_addr`
prescribe default bounds on the addresses Pool is allowed to allocate; the
placement of the internal bookkeeping must respect these.
The provided ranges cannot feature overlap among different allocated
types, or between an allocated type with one of kReserved or kPeripheral;
otherwise, arbitrary overlap is permitted.
fit::failed is returned if there is insufficient free RAM to use for
Pool's initial bookkeeping.
Defined at line 143 of file ../../zircon/kernel/phys/lib/memalloc/include/lib/memalloc/pool.h
template <size_t N>
fit::result<fit::failed> Init (std::array<std::span<Range>, N> ranges, uint64_t default_min_addr, uint64_t default_max_addr)
Initializes a Pool from a variable number of memory ranges, performing an
internal allocation for its internal bookkeeping among the free RAM
encoded in the provided ranges. `default_min_addr` and `default_max_addr`
prescribe default bounds on the addresses Pool is allowed to allocate; the
placement of the internal bookkeeping must respect these.
The provided ranges cannot feature overlap among different allocated
types, or between an allocated type with one of kReserved or kPeripheral;
otherwise, arbitrary overlap is permitted.
fit::failed is returned if there is insufficient free RAM to use for
Pool's initial bookkeeping.
Defined at line 143 of file ../../zircon/kernel/phys/lib/memalloc/include/lib/memalloc/pool.h
template <size_t N>
fit::result<fit::failed> Init (std::array<std::span<Range>, N> ranges, uint64_t default_min_addr, uint64_t default_max_addr)
Initializes a Pool from a variable number of memory ranges, performing an
internal allocation for its internal bookkeeping among the free RAM
encoded in the provided ranges. `default_min_addr` and `default_max_addr`
prescribe default bounds on the addresses Pool is allowed to allocate; the
placement of the internal bookkeeping must respect these.
The provided ranges cannot feature overlap among different allocated
types, or between an allocated type with one of kReserved or kPeripheral;
otherwise, arbitrary overlap is permitted.
fit::failed is returned if there is insufficient free RAM to use for
Pool's initial bookkeeping.
Defined at line 143 of file ../../zircon/kernel/phys/lib/memalloc/include/lib/memalloc/pool.h
template <size_t N>
fit::result<fit::failed> Init (std::array<std::span<Range>, N> ranges, uint64_t default_min_addr, uint64_t default_max_addr)
Initializes a Pool from a variable number of memory ranges, performing an
internal allocation for its internal bookkeeping among the free RAM
encoded in the provided ranges. `default_min_addr` and `default_max_addr`
prescribe default bounds on the addresses Pool is allowed to allocate; the
placement of the internal bookkeeping must respect these.
The provided ranges cannot feature overlap among different allocated
types, or between an allocated type with one of kReserved or kPeripheral;
otherwise, arbitrary overlap is permitted.
fit::failed is returned if there is insufficient free RAM to use for
Pool's initial bookkeeping.
Defined at line 143 of file ../../zircon/kernel/phys/lib/memalloc/include/lib/memalloc/pool.h
iterator begin ()
Defined at line 152 of file ../../zircon/kernel/phys/lib/memalloc/include/lib/memalloc/pool.h
iterator end ()
Defined at line 153 of file ../../zircon/kernel/phys/lib/memalloc/include/lib/memalloc/pool.h
bool empty ()
Defined at line 155 of file ../../zircon/kernel/phys/lib/memalloc/include/lib/memalloc/pool.h
const Range & front ()
Defined at line 157 of file ../../zircon/kernel/phys/lib/memalloc/include/lib/memalloc/pool.h
const Range & back ()
Defined at line 162 of file ../../zircon/kernel/phys/lib/memalloc/include/lib/memalloc/pool.h
size_t size ()
Returns the number of tracked, normalized ranges.
Defined at line 168 of file ../../zircon/kernel/phys/lib/memalloc/include/lib/memalloc/pool.h
void set_access_callback (AccessCallback access_callback)
Sets an allocation callback (see AccessCallback for more details). This
may be called before Init().
Defined at line 172 of file ../../zircon/kernel/phys/lib/memalloc/include/lib/memalloc/pool.h
void set_access_callback (AccessCallback access_callback)
Sets an allocation callback (see AccessCallback for more details). This
may be called before Init().
Defined at line 172 of file ../../zircon/kernel/phys/lib/memalloc/include/lib/memalloc/pool.h
void set_access_callback (AccessCallback access_callback)
Sets an allocation callback (see AccessCallback for more details). This
may be called before Init().
Defined at line 172 of file ../../zircon/kernel/phys/lib/memalloc/include/lib/memalloc/pool.h
void set_access_callback (AccessCallback access_callback)
Sets an allocation callback (see AccessCallback for more details). This
may be called before Init().
Defined at line 172 of file ../../zircon/kernel/phys/lib/memalloc/include/lib/memalloc/pool.h
fit::result<fit::failed, uint64_t> Allocate (Type type, uint64_t size, uint64_t alignment, std::optional<uint64_t> min_addr, std::optional<uint64_t> max_addr)
Attempts to allocate memory out of free RAM of the prescribed type, size,
and alignment. An optional upper address bound may be passed: if
unspecified the default upper bound passed to Init() will be respected.
`type` must be an allocated type. `size` must be positive and the following
must hold:
`min_addr.value_or(default_min_addr)
<
= max_addr.value_or(default_max_addr)`
Any returned address is guaranteed to be nonzero.
fit::failed is returned if there is insufficient free RAM to track any
new ranges or if there is no free RAM that meets the given constraints.
Defined at line 177 of file ../../zircon/kernel/phys/lib/memalloc/pool.cc
fit::result<fit::failed, uint64_t> Allocate (Type type, uint64_t size, uint64_t alignment, std::optional<uint64_t> min_addr, std::optional<uint64_t> max_addr)
Attempts to allocate memory out of free RAM of the prescribed type, size,
and alignment. An optional upper address bound may be passed: if
unspecified the default upper bound passed to Init() will be respected.
`type` must be an allocated type. `size` must be positive and the following
must hold:
`min_addr.value_or(default_min_addr)
<
= max_addr.value_or(default_max_addr)`
Any returned address is guaranteed to be nonzero.
fit::failed is returned if there is insufficient free RAM to track any
new ranges or if there is no free RAM that meets the given constraints.
Defined at line 177 of file ../../zircon/kernel/phys/lib/memalloc/pool.cc
fit::result<fit::failed, uint64_t> Allocate (Type type, uint64_t size, uint64_t alignment, std::optional<uint64_t> min_addr, std::optional<uint64_t> max_addr)
Attempts to allocate memory out of free RAM of the prescribed type, size,
and alignment. An optional upper address bound may be passed: if
unspecified the default upper bound passed to Init() will be respected.
`type` must be an allocated type. `size` must be positive and the following
must hold:
`min_addr.value_or(default_min_addr)
<
= max_addr.value_or(default_max_addr)`
Any returned address is guaranteed to be nonzero.
fit::failed is returned if there is insufficient free RAM to track any
new ranges or if there is no free RAM that meets the given constraints.
Defined at line 177 of file ../../zircon/kernel/phys/lib/memalloc/pool.cc
iterator FindContainingRange (uint64_t addr)
Returns an iterator pointing to the tracked, normalized range containing
the provided address if one exists, or else end().
Defined at line 179 of file ../../zircon/kernel/phys/lib/memalloc/include/lib/memalloc/pool.h
iterator FindContainingRange (uint64_t addr)
Returns an iterator pointing to the tracked, normalized range containing
the provided address if one exists, or else end().
Defined at line 179 of file ../../zircon/kernel/phys/lib/memalloc/include/lib/memalloc/pool.h
fit::result<fit::failed> MarkAsPeripheral (const memalloc::Range & range)
Returns `fit::success` if the provided range was succesully marked as peripheral. This requires
that `range.type` is `memalloc::Type::kPeripheral` and that there are no ranges of type
`memalloc::Type::kFreeRam` or allocated types overlapping in the range, otherwise `fit::failed`
is returned.
Defined at line 207 of file ../../zircon/kernel/phys/lib/memalloc/pool.cc
void PrintMemoryRanges (const char * prefix, FILE * f)
Pretty-prints the memory ranges contained in the pool.
Defined at line 277 of file ../../zircon/kernel/phys/lib/memalloc/include/lib/memalloc/pool.h
void PrintMemoryRanges (const char * prefix, FILE * f)
Pretty-prints the memory ranges contained in the pool.
Defined at line 277 of file ../../zircon/kernel/phys/lib/memalloc/include/lib/memalloc/pool.h
fit::result<fit::failed> UpdateRamSubranges (Type type, uint64_t addr, uint64_t size)
Destructively reallocates all RAM types within the given range to the
provided allocated type.
`addr + size` cannot exceed UINT64_MAX.
The utility of this method lies in situations where there is a special
range that we ultimately want to reserve for another booting context that
we are handing pool bookkeeping off to. For example, when loading a
fixed-address kernel image, we would want to prevent page tables - which
must persist across the boot - from being allocated out of that load range.
fit::failed is returned if there is insufficient bookkeeping to track any
new ranges of memory.
Defined at line 563 of file ../../zircon/kernel/phys/lib/memalloc/pool.cc
fit::result<fit::failed> UpdateRamSubranges (Type type, uint64_t addr, uint64_t size)
Destructively reallocates all RAM types within the given range to the
provided allocated type.
`addr + size` cannot exceed UINT64_MAX.
The utility of this method lies in situations where there is a special
range that we ultimately want to reserve for another booting context that
we are handing pool bookkeeping off to. For example, when loading a
fixed-address kernel image, we would want to prevent page tables - which
must persist across the boot - from being allocated out of that load range.
fit::failed is returned if there is insufficient bookkeeping to track any
new ranges of memory.
Defined at line 563 of file ../../zircon/kernel/phys/lib/memalloc/pool.cc
fit::result<fit::failed> Free (uint64_t addr, uint64_t size)
Attempts to free a subrange of a previously allocated range or one of
an allocated type that had previously been passed to Init(). This subrange
is updated to have type kFreeRam.
Freeing a range already tracked as kFreeRam is a no-op.
fit::failed is returned if there is insufficient memory to track the new
(subdivided) ranges of memory that would result from freeing.
Defined at line 408 of file ../../zircon/kernel/phys/lib/memalloc/pool.cc
fit::result<fit::failed> Free (uint64_t addr, uint64_t size)
Attempts to free a subrange of a previously allocated range or one of
an allocated type that had previously been passed to Init(). This subrange
is updated to have type kFreeRam.
Freeing a range already tracked as kFreeRam is a no-op.
fit::failed is returned if there is insufficient memory to track the new
(subdivided) ranges of memory that would result from freeing.
Defined at line 408 of file ../../zircon/kernel/phys/lib/memalloc/pool.cc
fit::result<fit::failed, uint64_t> Resize (const Range & original, uint64_t new_size, uint64_t min_alignment)
Attempts to resize a previously allocated range or one of the ranges of
allocated type originally passed to Init(). The resizing occurs only at
the level of bookkeeping; the start of the resized region is returned and,
if it differs from the one originally supplied, it is the responsibility
of the caller to actually std::memmove the old contents to the new region
before another allocation is performed. If the new size is smaller than
the original, then this method effectively just frees the range's tail.
The original range - as opposed to just its root address - is required to
be passed in as testimony; since the original allocation or
initialization, the pool may have coalesced neighbouring regions into it
or freed subregions of it, this method asserts that the associated tracked
range does at least still have `original` as a subrange with the
appropriate type. The provided range must also be of allocated type.
`new_size` must be positive; this method is not a backdoor `Free()`. The
original range must already be `min_alignment`-aligned.
fit::failed is returned if there is insufficient memory to track the new
(subdivided) ranges of memory that would result from resizing, or if the
range is untracked. No failure mode will leave the original range freed.
Defined at line 441 of file ../../zircon/kernel/phys/lib/memalloc/pool.cc
fit::result<fit::failed, uint64_t> Resize (const Range & original, uint64_t new_size, uint64_t min_alignment)
Attempts to resize a previously allocated range or one of the ranges of
allocated type originally passed to Init(). The resizing occurs only at
the level of bookkeeping; the start of the resized region is returned and,
if it differs from the one originally supplied, it is the responsibility
of the caller to actually std::memmove the old contents to the new region
before another allocation is performed. If the new size is smaller than
the original, then this method effectively just frees the range's tail.
The original range - as opposed to just its root address - is required to
be passed in as testimony; since the original allocation or
initialization, the pool may have coalesced neighbouring regions into it
or freed subregions of it, this method asserts that the associated tracked
range does at least still have `original` as a subrange with the
appropriate type. The provided range must also be of allocated type.
`new_size` must be positive; this method is not a backdoor `Free()`. The
original range must already be `min_alignment`-aligned.
fit::failed is returned if there is insufficient memory to track the new
(subdivided) ranges of memory that would result from resizing, or if the
range is untracked. No failure mode will leave the original range freed.
Defined at line 441 of file ../../zircon/kernel/phys/lib/memalloc/pool.cc
fit::result<fit::failed> TruncateTotalRam (uint64_t new_capacity_bytes)
Effectively truncates all of RAM (free or allocated) by allocating all of
it past the provided capacity as type kTruncatedRam. This is used to
simulate physical memory constraints of smaller devices. Any allocations
(including pool bookkeeping) past the cut-off are destructively
reallocated (via UpdateRamSubranges()).
kNvram is excluded from this truncation, as such ranges are special and
are of diagnostic value even when simulating physical memory constraints.
Defined at line 594 of file ../../zircon/kernel/phys/lib/memalloc/pool.cc
fit::result<fit::failed> TruncateTotalRam (uint64_t new_capacity_bytes)
Effectively truncates all of RAM (free or allocated) by allocating all of
it past the provided capacity as type kTruncatedRam. This is used to
simulate physical memory constraints of smaller devices. Any allocations
(including pool bookkeeping) past the cut-off are destructively
reallocated (via UpdateRamSubranges()).
kNvram is excluded from this truncation, as such ranges are special and
are of diagnostic value even when simulating physical memory constraints.
Defined at line 594 of file ../../zircon/kernel/phys/lib/memalloc/pool.cc
fit::result<fit::failed> CoalescePeripherals (std::span<const size_t> alignments)
This method will generate one peripheral range for every run of consecutive peripheral ranges
the pool knows of. This peripheral range will be aligned to oen of the provided alignments.
Each of the provided alignments is tried, and the first one not to generate invalid ranges,
such as overlapping with free ram ranges, is selected.
`alignments` is a collection of power of two alignments, that is the mask for alignment is
equivalent to `(1
<
<
alignments[n]) - 1`.
Defined at line 306 of file ../../zircon/kernel/phys/lib/memalloc/pool.cc
fit::result<fit::failed> CoalescePeripherals (std::span<const size_t> alignments)
This method will generate one peripheral range for every run of consecutive peripheral ranges
the pool knows of. This peripheral range will be aligned to oen of the provided alignments.
Each of the provided alignments is tried, and the first one not to generate invalid ranges,
such as overlapping with free ram ranges, is selected.
`alignments` is a collection of power of two alignments, that is the mask for alignment is
equivalent to `(1
<
<
alignments[n]) - 1`.
Defined at line 306 of file ../../zircon/kernel/phys/lib/memalloc/pool.cc
fit::result<fit::failed> CoalescePeripherals (std::span<const size_t> alignments)
This method will generate one peripheral range for every run of consecutive peripheral ranges
the pool knows of. This peripheral range will be aligned to oen of the provided alignments.
Each of the provided alignments is tried, and the first one not to generate invalid ranges,
such as overlapping with free ram ranges, is selected.
`alignments` is a collection of power of two alignments, that is the mask for alignment is
equivalent to `(1
<
<
alignments[n]) - 1`.
Defined at line 306 of file ../../zircon/kernel/phys/lib/memalloc/pool.cc
fit::result<fit::failed> CoalescePeripherals (std::span<const size_t> alignments)
This method will generate one peripheral range for every run of consecutive peripheral ranges
the pool knows of. This peripheral range will be aligned to oen of the provided alignments.
Each of the provided alignments is tried, and the first one not to generate invalid ranges,
such as overlapping with free ram ranges, is selected.
`alignments` is a collection of power of two alignments, that is the mask for alignment is
equivalent to `(1
<
<
alignments[n]) - 1`.
Defined at line 306 of file ../../zircon/kernel/phys/lib/memalloc/pool.cc