Skip to main content

BuddyAllocator

Struct BuddyAllocator 

Source
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

Source

pub const fn new() -> Self

Creates a new instance.

Source

pub fn init(&mut self, memory_regions: &[MemoryRegion])

Performs the init operation.

Source

fn pass_count(&mut self, memory_regions: &[MemoryRegion])

Performs the pass count operation.

Source

fn pass_reserve_segment_storage(&mut self, memory_regions: &[MemoryRegion])

Reserve per-zone segment tables sized to the actual fragmented layout.

Source

fn pass_reserve_bitmap_pools(&mut self, memory_regions: &[MemoryRegion])

Reserve per-zone bitmap pools using a segmentation-safe upper bound.

Source

fn pass_finalize_zone_accounting(&mut self)

Finalise zone accounting once the managed segment set is known.

Source

fn watermark_target_pages( managed_pages: usize, divisor: usize, floor: usize, cap: usize, ) -> usize

Compute a bounded watermark target for a zone.

Source

fn lowmem_reserve_target_pages( zone_type: ZoneType, managed_pages: usize, ) -> usize

Compute a bounded low-memory reserve target.

Source

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.

Source

fn pass_build_segments(&mut self, memory_regions: &[MemoryRegion])

Build the final segmented physical layout from remaining boot allocator ranges.

Source

fn pass_setup_segment_bitmaps(&mut self)

Assign bitmap slices to each populated segment.

Source

fn pass_populate(&mut self)

Seed each contiguous segment with greedy block insertion.

Source

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.

Source

fn alloc_from_zone( zone: &mut Zone, zone_idx: usize, order: u8, migratetype: Migratetype, honor_watermarks: bool, token: &IrqDisabledToken, ) -> Option<PhysFrame>

Allocates from zone.

Source

fn alloc_from_segment( segment: &mut ZoneSegment, order: u8, requested_migratetype: Migratetype, _token: &IrqDisabledToken, ) -> Option<u64>

Allocate from one contiguous segment.

Source

fn find_segment_index(zone: &Zone, phys: u64, order: u8) -> Option<usize>

Source

fn segment_contains_block(segment: &ZoneSegment, phys: u64, order: u8) -> bool

Source

fn free_to_zone( zone: &mut Zone, frame: PhysFrame, order: u8, _token: &IrqDisabledToken, )

Releases to zone.

Source

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.

Source

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.

Source

fn page_index(segment: &ZoneSegment, phys: u64) -> usize

Performs the page index operation.

Source

fn pair_index(segment: &ZoneSegment, phys: u64, order: u8) -> usize

Performs the pair index operation.

Source

fn toggle_pair(segment: &mut ZoneSegment, phys: u64, order: u8) -> bool

Performs the toggle pair operation.

Source

fn buddy_phys(segment: &ZoneSegment, phys: u64, order: u8) -> Option<u64>

Performs the buddy phys operation.

Source

fn mark_allocated( segment: &mut ZoneSegment, frame_phys: u64, order: u8, allocated: bool, )

Performs the mark allocated operation.

Source

fn free_list_push( segment: &mut ZoneSegment, phys: u64, order: u8, migratetype: Migratetype, )

Releases list push.

Source

fn free_list_pop( segment: &mut ZoneSegment, order: u8, migratetype: Migratetype, ) -> Option<u64>

Releases list pop.

Source

fn free_list_remove( segment: &mut ZoneSegment, phys: u64, order: u8, migratetype: Migratetype, ) -> bool

Releases list remove.

Source

fn read_free_next(phys: u64) -> u64

Reads free next.

Source

fn write_free_next(phys: u64, next: u64)

Writes free next.

Source

fn read_free_prev(phys: u64) -> u64

Reads free prev.

Source

fn write_free_prev(phys: u64, prev: u64)

Writes free prev.

Source

fn zone_index_for_addr(addr: u64) -> usize

Performs the zone index for addr operation.

Source

fn zone_bounds(zone_idx: usize) -> (u64, u64)

Performs the zone bounds operation.

Source

fn zone_intersection_aligned( region: &MemoryRegion, zone_idx: usize, ) -> Option<(u64, u64)>

Performs the zone intersection aligned operation.

Source

fn protected_overlap_end(start: u64, end: u64) -> Option<u64>

Performs the protected overlap end operation.

Source

fn protected_module_ranges() -> [Option<(u64, u64)>; 32]

Performs the protected module ranges operation.

Source

fn pairs_for_order(span_pages: usize, order: u8) -> usize

Performs the pairs for order operation.

Source

fn bits_to_bytes(bits: usize) -> usize

Performs the bits to bytes operation.

Source

fn bitmap_bytes_for_span(span_pages: usize) -> usize

Performs the bitmap bytes for span operation.

Source

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.

Source

fn pageblock_tag_bytes_for_span(span_pages: usize) -> usize

Exact byte count required for pageblock migratetype tags over one contiguous span.

Source

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.

Source

fn align_up(value: u64, align: u64) -> u64

Performs the align up operation.

Source

fn align_down(value: u64, align: u64) -> u64

Performs the align down operation.

Source

fn default_pageblock_migratetype(zone_type: ZoneType) -> Migratetype

Default pageblock migratetype assigned at bootstrap for one zone.

Source

fn pageblock_index(segment: &ZoneSegment, phys: u64) -> usize

Returns the pageblock index covering phys inside segment.

Source

fn decode_pageblock_tag(tag: u8) -> Migratetype

Decode one pageblock tag byte into a migratetype.

Source

fn pageblock_migratetype( segment: &ZoneSegment, phys: u64, fallback: Migratetype, ) -> Migratetype

Returns the current pageblock migratetype for a block start.

Source

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).

Source

fn zone_pageblock_counts(zone: &Zone) -> [usize; 2]

Count pageblocks by migratetype for one zone.

Source

fn zone_effective_free_pages(zone: &Zone, zone_idx: usize) -> usize

Source

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.

Source

fn can_merge_with_buddy(phys: u64, order: u8, migratetype: Migratetype) -> bool

Returns whether a buddy block is free and coalescible with migratetype.

Source

fn block_migratetype(frame_phys: u64) -> Migratetype

Decode the block migratetype stored in frame metadata flags.

Source

fn migratetype_from_flags(flags: u32) -> Migratetype

Decode a migratetype from frame flags.

Source

fn free_flags_for(migratetype: Migratetype) -> u32

Encode the metadata flags for a free block of the given migratetype.

Source

fn allocated_flags_for(migratetype: Migratetype) -> u32

Encode the metadata flags for an allocated block of the given migratetype.

Source

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.

Source

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.

Source

fn zone_pressure_for_free_pages(zone: &Zone, free_pages: usize) -> ZonePressure

Source

fn compaction_candidate( &self, order: u8, migratetype: Migratetype, zone_order: &[usize], ) -> Option<CompactionCandidate>

Source

fn compaction_drain_budget(candidate: CompactionCandidate) -> usize

Source

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.

Source

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.

Source

fn mark_block_allocated(frame_phys: u64, order: u8, migratetype: Migratetype)

Source

fn mark_block_free(frame_phys: u64, order: u8, migratetype: Migratetype)

Source

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

Source

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).

Source

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

Source

pub fn page_totals(&self) -> (usize, usize)

Fast totals without heap allocation (safe in low-level paths).

Source

pub fn get_zone(&self, idx: usize) -> &Zone

Get a reference to a zone by index.

Source

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

Source§

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)

Performs the free operation.

Source§

fn alloc_frame( &mut self, token: &IrqDisabledToken, ) -> Result<PhysFrame, AllocError>

Allocate a single frame (convenience method)

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts 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 more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts 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
§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.