pub struct BuddyAllocator {
zones: [Zone; 3],
bitmap_pool: [(u64, u64); 3],
}Fields§
§zones: [Zone; 3]§bitmap_pool: [(u64, u64); 3]Per-zone bitmap pool reserved from free memory: [start, end).
Implementations§
Source§impl BuddyAllocator
impl BuddyAllocator
Sourcepub fn init(&mut self, memory_regions: &[MemoryRegion])
pub fn init(&mut self, memory_regions: &[MemoryRegion])
Performs the init operation.
Sourcefn pass_count(&mut self, memory_regions: &[MemoryRegion])
fn pass_count(&mut self, memory_regions: &[MemoryRegion])
Performs the pass count operation.
Sourcefn pass_reserve_segment_storage(&mut self, memory_regions: &[MemoryRegion])
fn pass_reserve_segment_storage(&mut self, memory_regions: &[MemoryRegion])
Reserve per-zone segment tables sized to the actual fragmented layout.
Sourcefn pass_reserve_bitmap_pools(&mut self, memory_regions: &[MemoryRegion])
fn pass_reserve_bitmap_pools(&mut self, memory_regions: &[MemoryRegion])
Reserve per-zone bitmap pools using a segmentation-safe upper bound.
Sourcefn pass_finalize_zone_accounting(&mut self)
fn pass_finalize_zone_accounting(&mut self)
Finalise zone accounting once the managed segment set is known.
Sourcefn watermark_target_pages(
managed_pages: usize,
divisor: usize,
floor: usize,
cap: usize,
) -> usize
fn watermark_target_pages( managed_pages: usize, divisor: usize, floor: usize, cap: usize, ) -> usize
Compute a bounded watermark target for a zone.
Sourcefn lowmem_reserve_target_pages(
zone_type: ZoneType,
managed_pages: usize,
) -> usize
fn lowmem_reserve_target_pages( zone_type: ZoneType, managed_pages: usize, ) -> usize
Compute a bounded low-memory reserve target.
Sourcefn bounded_zone_target(
managed_pages: usize,
divisor: usize,
floor: usize,
cap: usize,
max_fraction_divisor: usize,
) -> usize
fn bounded_zone_target( managed_pages: usize, divisor: usize, floor: usize, cap: usize, max_fraction_divisor: usize, ) -> usize
Bound a policy target to something meaningful for the current zone size.
Sourcefn pass_build_segments(&mut self, memory_regions: &[MemoryRegion])
fn pass_build_segments(&mut self, memory_regions: &[MemoryRegion])
Build the final segmented physical layout from remaining boot allocator ranges.
Sourcefn pass_setup_segment_bitmaps(&mut self)
fn pass_setup_segment_bitmaps(&mut self)
Assign bitmap slices to each populated segment.
Sourcefn pass_populate(&mut self)
fn pass_populate(&mut self)
Seed each contiguous segment with greedy block insertion.
Sourcefn seed_range_as_free(
zone_type: ZoneType,
segment: &mut ZoneSegment,
start: u64,
end: u64,
)
fn seed_range_as_free( zone_type: ZoneType, segment: &mut ZoneSegment, start: u64, end: u64, )
Seeds a contiguous physical range [start, end) as free using greedy block insertion.
Unlike the previous min/max span design, segment is guaranteed to be a
genuinely contiguous free extent. Greedy seeding therefore improves boot
time without ever making holes visible to the buddy topology.
Sourcefn alloc_from_zone(
zone: &mut Zone,
zone_idx: usize,
order: u8,
migratetype: Migratetype,
honor_watermarks: bool,
token: &IrqDisabledToken,
) -> Option<PhysFrame>
fn alloc_from_zone( zone: &mut Zone, zone_idx: usize, order: u8, migratetype: Migratetype, honor_watermarks: bool, token: &IrqDisabledToken, ) -> Option<PhysFrame>
Allocates from zone.
Sourcefn alloc_from_segment(
segment: &mut ZoneSegment,
order: u8,
requested_migratetype: Migratetype,
_token: &IrqDisabledToken,
) -> Option<u64>
fn alloc_from_segment( segment: &mut ZoneSegment, order: u8, requested_migratetype: Migratetype, _token: &IrqDisabledToken, ) -> Option<u64>
Allocate from one contiguous segment.
fn find_segment_index(zone: &Zone, phys: u64, order: u8) -> Option<usize>
fn segment_contains_block(segment: &ZoneSegment, phys: u64, order: u8) -> bool
Sourcefn free_to_zone(
zone: &mut Zone,
frame: PhysFrame,
order: u8,
_token: &IrqDisabledToken,
)
fn free_to_zone( zone: &mut Zone, frame: PhysFrame, order: u8, _token: &IrqDisabledToken, )
Releases to zone.
Sourcefn quarantine_poisoned_block_in_zone(
zone: &mut Zone,
frame: PhysFrame,
order: u8,
_token: &IrqDisabledToken,
)
fn quarantine_poisoned_block_in_zone( zone: &mut Zone, frame: PhysFrame, order: u8, _token: &IrqDisabledToken, )
Drops allocator accounting for a poisoned block without returning it to the free list.
The block is not placed on any free list and its debug-bitmap entries remain marked as “allocated” : because they genuinely are: the pages are quarantined and inaccessible. Clearing them would defeat the double-free detector for any later attempt to free the same block.
Sourcefn insert_free_block(
segment: &mut ZoneSegment,
frame_phys: u64,
initial_order: u8,
migratetype: Migratetype,
)
fn insert_free_block( segment: &mut ZoneSegment, frame_phys: u64, initial_order: u8, migratetype: Migratetype, )
Linux-style parity-map coalescing insertion. Returns after inserting the (potentially coalesced) block into the appropriate free list, without recursing further. If the buddy bit is already set or we reach MAX_ORDER, the block is inserted as-is. Otherwise, the buddy block is removed from its free list and coalesced with the current block, and the process repeats at the next order.
Sourcefn page_index(segment: &ZoneSegment, phys: u64) -> usize
fn page_index(segment: &ZoneSegment, phys: u64) -> usize
Performs the page index operation.
Sourcefn pair_index(segment: &ZoneSegment, phys: u64, order: u8) -> usize
fn pair_index(segment: &ZoneSegment, phys: u64, order: u8) -> usize
Performs the pair index operation.
Sourcefn toggle_pair(segment: &mut ZoneSegment, phys: u64, order: u8) -> bool
fn toggle_pair(segment: &mut ZoneSegment, phys: u64, order: u8) -> bool
Performs the toggle pair operation.
Sourcefn buddy_phys(segment: &ZoneSegment, phys: u64, order: u8) -> Option<u64>
fn buddy_phys(segment: &ZoneSegment, phys: u64, order: u8) -> Option<u64>
Performs the buddy phys operation.
Sourcefn mark_allocated(
segment: &mut ZoneSegment,
frame_phys: u64,
order: u8,
allocated: bool,
)
fn mark_allocated( segment: &mut ZoneSegment, frame_phys: u64, order: u8, allocated: bool, )
Performs the mark allocated operation.
Sourcefn free_list_push(
segment: &mut ZoneSegment,
phys: u64,
order: u8,
migratetype: Migratetype,
)
fn free_list_push( segment: &mut ZoneSegment, phys: u64, order: u8, migratetype: Migratetype, )
Releases list push.
Sourcefn free_list_pop(
segment: &mut ZoneSegment,
order: u8,
migratetype: Migratetype,
) -> Option<u64>
fn free_list_pop( segment: &mut ZoneSegment, order: u8, migratetype: Migratetype, ) -> Option<u64>
Releases list pop.
Sourcefn free_list_remove(
segment: &mut ZoneSegment,
phys: u64,
order: u8,
migratetype: Migratetype,
) -> bool
fn free_list_remove( segment: &mut ZoneSegment, phys: u64, order: u8, migratetype: Migratetype, ) -> bool
Releases list remove.
Sourcefn read_free_next(phys: u64) -> u64
fn read_free_next(phys: u64) -> u64
Reads free next.
Sourcefn write_free_next(phys: u64, next: u64)
fn write_free_next(phys: u64, next: u64)
Writes free next.
Sourcefn read_free_prev(phys: u64) -> u64
fn read_free_prev(phys: u64) -> u64
Reads free prev.
Sourcefn write_free_prev(phys: u64, prev: u64)
fn write_free_prev(phys: u64, prev: u64)
Writes free prev.
Sourcefn zone_index_for_addr(addr: u64) -> usize
fn zone_index_for_addr(addr: u64) -> usize
Performs the zone index for addr operation.
Sourcefn zone_bounds(zone_idx: usize) -> (u64, u64)
fn zone_bounds(zone_idx: usize) -> (u64, u64)
Performs the zone bounds operation.
Sourcefn zone_intersection_aligned(
region: &MemoryRegion,
zone_idx: usize,
) -> Option<(u64, u64)>
fn zone_intersection_aligned( region: &MemoryRegion, zone_idx: usize, ) -> Option<(u64, u64)>
Performs the zone intersection aligned operation.
Sourcefn protected_overlap_end(start: u64, end: u64) -> Option<u64>
fn protected_overlap_end(start: u64, end: u64) -> Option<u64>
Performs the protected overlap end operation.
Sourcefn protected_module_ranges() -> [Option<(u64, u64)>; 32]
fn protected_module_ranges() -> [Option<(u64, u64)>; 32]
Performs the protected module ranges operation.
Sourcefn pairs_for_order(span_pages: usize, order: u8) -> usize
fn pairs_for_order(span_pages: usize, order: u8) -> usize
Performs the pairs for order operation.
Sourcefn bits_to_bytes(bits: usize) -> usize
fn bits_to_bytes(bits: usize) -> usize
Performs the bits to bytes operation.
Sourcefn bitmap_bytes_for_span(span_pages: usize) -> usize
fn bitmap_bytes_for_span(span_pages: usize) -> usize
Performs the bitmap bytes for span operation.
Sourcefn bitmap_bytes_upper_bound_for_pages(page_count: usize) -> usize
fn bitmap_bytes_upper_bound_for_pages(page_count: usize) -> usize
Upper bound for bitmap storage over any segmentation of page_count pages.
For one page, every order contributes at most one parity bit. Summing that pessimistic bound across all pages yields a simple safe allocation bound, even if bitmap-pool reservations split ranges further.
Sourcefn pageblock_tag_bytes_for_span(span_pages: usize) -> usize
fn pageblock_tag_bytes_for_span(span_pages: usize) -> usize
Exact byte count required for pageblock migratetype tags over one contiguous span.
Sourcefn pageblock_tag_bytes_upper_bound_for_pages(page_count: usize) -> usize
fn pageblock_tag_bytes_upper_bound_for_pages(page_count: usize) -> usize
Safe upper bound for pageblock-tag storage across any segmentation of page_count pages.
Sourcefn align_down(value: u64, align: u64) -> u64
fn align_down(value: u64, align: u64) -> u64
Performs the align down operation.
Sourcefn default_pageblock_migratetype(zone_type: ZoneType) -> Migratetype
fn default_pageblock_migratetype(zone_type: ZoneType) -> Migratetype
Default pageblock migratetype assigned at bootstrap for one zone.
Sourcefn pageblock_index(segment: &ZoneSegment, phys: u64) -> usize
fn pageblock_index(segment: &ZoneSegment, phys: u64) -> usize
Returns the pageblock index covering phys inside segment.
Sourcefn decode_pageblock_tag(tag: u8) -> Migratetype
fn decode_pageblock_tag(tag: u8) -> Migratetype
Decode one pageblock tag byte into a migratetype.
Sourcefn pageblock_migratetype(
segment: &ZoneSegment,
phys: u64,
fallback: Migratetype,
) -> Migratetype
fn pageblock_migratetype( segment: &ZoneSegment, phys: u64, fallback: Migratetype, ) -> Migratetype
Returns the current pageblock migratetype for a block start.
Sourcefn retag_pageblock_range(
segment: &mut ZoneSegment,
phys: u64,
order: u8,
migratetype: Migratetype,
)
fn retag_pageblock_range( segment: &mut ZoneSegment, phys: u64, order: u8, migratetype: Migratetype, )
Retag every pageblock overlapped by the buddy block [phys, phys + 2^order * PAGE_SIZE).
Sourcefn zone_pageblock_counts(zone: &Zone) -> [usize; 2]
fn zone_pageblock_counts(zone: &Zone) -> [usize; 2]
Count pageblocks by migratetype for one zone.
fn zone_effective_free_pages(zone: &Zone, zone_idx: usize) -> usize
Sourcefn zone_allows_allocation(
zone: &Zone,
zone_idx: usize,
order: u8,
honor_watermarks: bool,
) -> bool
fn zone_allows_allocation( zone: &Zone, zone_idx: usize, order: u8, honor_watermarks: bool, ) -> bool
Returns whether the zone should be considered for the current request.
Sourcefn can_merge_with_buddy(phys: u64, order: u8, migratetype: Migratetype) -> bool
fn can_merge_with_buddy(phys: u64, order: u8, migratetype: Migratetype) -> bool
Returns whether a buddy block is free and coalescible with migratetype.
Sourcefn block_migratetype(frame_phys: u64) -> Migratetype
fn block_migratetype(frame_phys: u64) -> Migratetype
Decode the block migratetype stored in frame metadata flags.
Sourcefn migratetype_from_flags(flags: u32) -> Migratetype
fn migratetype_from_flags(flags: u32) -> Migratetype
Decode a migratetype from frame flags.
Sourcefn free_flags_for(migratetype: Migratetype) -> u32
fn free_flags_for(migratetype: Migratetype) -> u32
Encode the metadata flags for a free block of the given migratetype.
Sourcefn allocated_flags_for(migratetype: Migratetype) -> u32
fn allocated_flags_for(migratetype: Migratetype) -> u32
Encode the metadata flags for an allocated block of the given migratetype.
Sourcefn alloc_in_zone_order(
&mut self,
order: u8,
migratetype: Migratetype,
zone_order: &[usize],
token: &IrqDisabledToken,
) -> Option<PhysFrame>
fn alloc_in_zone_order( &mut self, order: u8, migratetype: Migratetype, zone_order: &[usize], token: &IrqDisabledToken, ) -> Option<PhysFrame>
Try to allocate from the supplied zone order, first honoring reserves and then bypassing them.
Sourcefn preferred_zone_order(migratetype: Migratetype) -> &'static [usize; 3]
fn preferred_zone_order(migratetype: Migratetype) -> &'static [usize; 3]
Returns the preferred zone scan order for one migratetype.
Unmovable allocations still prefer Normal first because the current
kernel hot-touches those pages directly. Movable allocations instead
prefer HighMem first to preserve scarce low memory for pinned kernel
structures and emergency paths.
fn zone_pressure_for_free_pages(zone: &Zone, free_pages: usize) -> ZonePressure
fn compaction_candidate( &self, order: u8, migratetype: Migratetype, zone_order: &[usize], ) -> Option<CompactionCandidate>
fn compaction_drain_budget(candidate: CompactionCandidate) -> usize
Sourcefn alloc_locked_with_migratetype(
&mut self,
order: u8,
migratetype: Migratetype,
token: &IrqDisabledToken,
) -> Result<PhysFrame, AllocError>
fn alloc_locked_with_migratetype( &mut self, order: u8, migratetype: Migratetype, token: &IrqDisabledToken, ) -> Result<PhysFrame, AllocError>
Allocate while the caller already owns the global allocator lock.
Sourcefn alloc_zone_locked(
&mut self,
order: u8,
zone: ZoneType,
migratetype: Migratetype,
token: &IrqDisabledToken,
) -> Result<PhysFrame, AllocError>
fn alloc_zone_locked( &mut self, order: u8, zone: ZoneType, migratetype: Migratetype, token: &IrqDisabledToken, ) -> Result<PhysFrame, AllocError>
Allocate from one explicit zone while the caller already owns the global allocator lock.
fn mark_block_allocated(frame_phys: u64, order: u8, migratetype: Migratetype)
fn mark_block_free(frame_phys: u64, order: u8, migratetype: Migratetype)
Sourcefn set_block_meta(frame_phys: u64, order: u8, flags: u32, refcount: u32)
fn set_block_meta(frame_phys: u64, order: u8, flags: u32, refcount: u32)
Stamp every 4 KiB [MetaSlot] in the buddy block (flags, order, free-list links, refcount).
[MetaSlot::reset_with_free_list_meta] runs on each page, including non-head pages
of a multi-page block: the whole block returns to the buddy as one unit, so vtable and
guard bits are cleared (except poison preserved per-slot) on every constituent frame.
Source§impl BuddyAllocator
impl BuddyAllocator
Sourcepub fn alloc_zone(
&mut self,
order: u8,
zone: ZoneType,
token: &IrqDisabledToken,
) -> Result<PhysFrame, AllocError>
pub fn alloc_zone( &mut self, order: u8, zone: ZoneType, token: &IrqDisabledToken, ) -> Result<PhysFrame, AllocError>
Allocate explicitly from one zone (e.g. DMA-only callers).
Sourcepub fn alloc_zone_migratetype(
&mut self,
order: u8,
zone: ZoneType,
migratetype: Migratetype,
token: &IrqDisabledToken,
) -> Result<PhysFrame, AllocError>
pub fn alloc_zone_migratetype( &mut self, order: u8, zone: ZoneType, migratetype: Migratetype, token: &IrqDisabledToken, ) -> Result<PhysFrame, AllocError>
Allocate explicitly from one zone with a migratetype hint.
This keeps the target zone fixed but still selects the preferred
free-list class and fallback donor order from migratetype.
Source§impl BuddyAllocator
impl BuddyAllocator
Sourcepub fn page_totals(&self) -> (usize, usize)
pub fn page_totals(&self) -> (usize, usize)
Fast totals without heap allocation (safe in low-level paths).
Sourcepub fn zone_snapshot(&self, out: &mut [ZoneStats]) -> usize
pub fn zone_snapshot(&self, out: &mut [ZoneStats]) -> usize
Snapshot zones without heap allocation.
Returns the number of entries written to out.
Trait Implementations§
Source§impl FrameAllocator for BuddyAllocator
impl FrameAllocator for BuddyAllocator
Source§fn alloc(
&mut self,
order: u8,
token: &IrqDisabledToken,
) -> Result<PhysFrame, AllocError>
fn alloc( &mut self, order: u8, token: &IrqDisabledToken, ) -> Result<PhysFrame, AllocError>
Performs the alloc operation.
Source§fn free(&mut self, frame: PhysFrame, order: u8, token: &IrqDisabledToken)
fn free(&mut self, frame: PhysFrame, order: u8, token: &IrqDisabledToken)
Performs the free operation.
Source§fn alloc_frame(
&mut self,
token: &IrqDisabledToken,
) -> Result<PhysFrame, AllocError>
fn alloc_frame( &mut self, token: &IrqDisabledToken, ) -> Result<PhysFrame, AllocError>
Auto Trait Implementations§
impl !Sync for BuddyAllocator
impl Freeze for BuddyAllocator
impl RefUnwindSafe for BuddyAllocator
impl Send for BuddyAllocator
impl Unpin for BuddyAllocator
impl UnsafeUnpin for BuddyAllocator
impl UnwindSafe for BuddyAllocator
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more