Skip to content

Memory Management

Physical/virtual memory management, allocators, and grants.

src/memory/emergency.rs

Memory pressure governor and sacred emergency frame reserve.

EMERGENCY_UI_FRAMES const

rust
const EMERGENCY_UI_FRAMES : usize

Fixed UI reserve — never touched by normal allocations.

PressureState enum

rust
enum PressureState {
    Normal = 0,
    Warning = 1,
    Emergency = 2,
    Evacuating = 3,
    Picker = 4,
    Restoring = 5,
}

buffer_frames fn

rust
fn buffer_frames() -> usize

reserve_frames fn

rust
fn reserve_frames() -> usize

state fn

rust
fn state() -> PressureState

set_state fn

rust
fn set_state(next : PressureState)

system_frozen fn

rust
fn system_frozen() -> bool

set_system_frozen fn

rust
fn set_system_frozen(frozen : bool)

emergency_watermark fn

rust
fn emergency_watermark() -> usize

warning_watermark_frames fn

rust
fn warning_watermark_frames(_total : usize, buffer : usize) -> usize

emergency_watermark_frames fn

rust
fn emergency_watermark_frames(_total : usize, _buffer : usize) -> usize

init_reserve fn

rust
fn init_reserve()

Initialize the sacred reserve after the physical memory allocator is ready.

check_before_alloc fn

rust
fn check_before_alloc() -> bool

Called before every normal frame allocation.

alloc_emergency_frame fn

rust
fn alloc_emergency_frame() -> Option<Frame>

Pop one frame from the UI portion of the sacred reserve (emergency path only).

on_oom fn

rust
fn on_oom()

stats_string fn

rust
fn stats_string(buf : &mut [u8]) -> usize

src/memory/kernel_mapper.rs

KernelMapper struct

rust
struct KernelMapper { /* … */ }

A guard to the global lock protecting the upper 128 TiB of kernel address space.

NOTE: Use this with great care! Since heap allocations may also require this lock when the heap needs to be expended, it must not be held while memory allocations are done!

src/memory/mod.rs

Memory management

Some code was borrowed from Phil Opp's Blog

free_frames fn

rust
fn free_frames() -> usize

Get the number of frames available

used_frames fn

rust
fn used_frames() -> usize

Get the number of frames used

total_frames fn

rust
fn total_frames() -> usize

allocate_p2frame fn

rust
fn allocate_p2frame(order : u32) -> Option<Frame>

Allocate a range of frames

allocate_frame fn

rust
fn allocate_frame() -> Option<Frame>

allocate_p2frame_complex fn

rust
fn allocate_p2frame_complex(_req_order : u32, _flags :(), _strategy : Option<()>, min_order : u32,) -> Option<(Frame, usize)>

deallocate_p2frame fn

rust
unsafe fn deallocate_p2frame(orig_frame : Frame, order : u32)

deallocate_frame fn

rust
unsafe fn deallocate_frame(frame : Frame)

map_device_memory fn

rust
unsafe fn map_device_memory(addr : PhysicalAddress, len : usize) -> VirtualAddress

Frame struct

rust
struct Frame { /* … */ }

Frame::containing fn

rust
fn containing(address : PhysicalAddress) -> Frame

Create a frame containing address

Frame::base fn

rust
fn base(self) -> PhysicalAddress

Get the address of this frame

Enomem struct

rust
struct Enomem { /* … */ }

RaiiFrame struct

rust
struct RaiiFrame { /* … */ }

PageInfo struct

rust
struct PageInfo { /* … */ }

Section struct

rust
struct Section { /* … */ }

MAX_SECTION_SIZE_BITS const

rust
const MAX_SECTION_SIZE_BITS : u32

MAX_SECTION_SIZE const

rust
const MAX_SECTION_SIZE : usize

MAX_SECTION_PAGE_COUNT const

rust
const MAX_SECTION_PAGE_COUNT : usize

init_mm fn

rust
fn init_mm(allocator : BumpAllocator<RmmA>)

AddRefError enum

rust
enum AddRefError {
    CowToShared,
    SharedToCow,
    RcOverflow,
}

RefKind enum

rust
enum RefKind {
    Cow,
    Shared,
}

RefCount enum

rust
enum RefCount {
    One,
    Shared,
    Cow,
}

get_page_info fn

rust
fn get_page_info(frame : Frame) -> Option<&'static PageInfo>

Segv struct

rust
struct Segv { /* … */ }

ArchIntCtx trait

rust
trait ArchIntCtx { /* … */ }

page_fault_handler fn

rust
fn page_fault_handler(stack : &mut impl ArchIntCtx, code : GenericPfFlags, faulting_address : VirtualAddress,) -> Result<(), Segv>

the_zeroed_frame fn

rust
fn the_zeroed_frame() ->(Frame, &'static PageInfo)

init_frame fn

rust
fn init_frame(init_rc : RefCount) -> Result<Frame, PfError>

TheFrameAllocator struct

rust
struct TheFrameAllocator { /* … */ }

src/startup/memory.rs

BootloaderMemoryKind enum

rust
enum BootloaderMemoryKind {
    Null = 0,
    Free = 1,
    Reclaim = 2,
    Reserved = 3,
    Kernel = 0x100,
    Device = 0x101,
    IdentityMap = 0x102,
}

register_memory_region fn

rust
fn register_memory_region(base : usize, size : usize, kind : BootloaderMemoryKind)

register_bootloader_areas fn

rust
fn register_bootloader_areas(areas_base : usize, areas_size : usize)

init fn

rust
unsafe fn init(low_limit : Option<usize>, high_limit : Option<usize>)

src/allocator/linked_list.rs

Allocator struct

rust
struct Allocator { /* … */ }

src/allocator/slab.rs

Allocator struct

rust
struct Allocator { /* … */ }

src/allocator/mod.rs

init fn

rust
unsafe fn init()

src/context/memory.rs

MMAP_MIN_DEFAULT const

rust
const MMAP_MIN_DEFAULT : usize

page_flags fn

rust
fn page_flags(flags : MapFlags) -> PageFlags<RmmA>

map_flags fn

rust
fn map_flags(page_flags : PageFlags<RmmA>) -> MapFlags

UnmapResult struct

rust
struct UnmapResult { /* … */ }

AddrSpaceWrapper struct

rust
struct AddrSpaceWrapper { /* … */ }

AddrSpace struct

rust
struct AddrSpace { /* … */ }

AddrSpaceWrapper::try_clone fn

rust
fn try_clone(&self) -> Result<Arc<AddrSpaceWrapper>>

Attempt to clone an existing address space so that all mappings are copied (CoW).

AddrSpaceWrapper::borrow_frame_enforce_rw_allocated fn

rust
fn borrow_frame_enforce_rw_allocated(self : &Arc<Self>, page : Page) -> Result<RaiiFrame>

Borrows a page from user memory, requiring that the frame be Allocated and read/write. This is intended to be used for user-kernel shared memory.

UserGrants struct

rust
struct UserGrants { /* … */ }

PageSpan struct

rust
struct PageSpan { /* … */ }

PageSpan::before fn

rust
fn before(self, span : Self) -> Option<Self>

Returns the span from the start of self until the start of the specified span.

PageSpan::after fn

rust
fn after(self, span : Self) -> Option<Self>

Returns the span from the end of the given span until the end of self.

PageSpan::between fn

rust
fn between(start : Page, end : Page) -> Self

Returns the span between two pages, [start, end), truncating to zero if end < start.

UserGrants::contains fn

rust
fn contains(&self, page : Page) -> Option<(Page, &GrantInfo)>

Returns the grant, if any, which occupies the specified page

UserGrants::conflicts fn

rust
fn conflicts(&self, span : PageSpan) -> impl Iterator<Item =(Page, &'_ GrantInfo)> + '_

Returns an iterator over all grants that occupy some part of the requested region

UserGrants::find_free_near fn

rust
fn find_free_near(&self, min : usize, page_count : usize, _near : Option<Page>,) -> Option<PageSpan>

Return a free region with the specified size

GrantInfo struct

rust
struct GrantInfo { /* … */ }

Provider enum

rust
enum Provider {
    Allocated,
    AllocatedShared,
    PhysBorrowed,
    External,
    FmapBorrowed,
}

Enumeration of various types of grants.

Grant struct

rust
struct Grant { /* … */ }

GrantFileRef struct

rust
struct GrantFileRef { /* … */ }

Grant::borrow fn

rust
fn borrow(src_address_space_lock : Arc<AddrSpaceWrapper>, src_address_space : &mut AddrSpace, src_base : Page, dst_base : Page, page_count : usize, map_flags : MapFlags, dst_mapper : &mut PageMapper, dst_flusher : &mut Flusher, eager : bool, _allow_phys : bool, is_pinned_userscheme_borrow : bool,) -> Result<Grant>

Borrow all pages in the range [src_base, src_base+page_count) from src_address_space, mapping them into [dst_base, dst_base+page_count). The destination pages will lazily read the page tables of the source pages, but once present in the destination address space, pages that are unmaped or moved will not be made visible to the destination address space.

Grant::transfer fn

rust
fn transfer(mut self, dst_base : Page, flags : PageFlags<RmmA>, src_mapper : &mut PageMapper, mut dst_mapper : Option<&mut PageMapper>, src_flusher : &mut Flusher, dst_flusher : &mut impl GenericFlusher,) -> Result<Grant>

Move a grant between two address spaces.

Grant::span fn

rust
fn span(&self) -> PageSpan

Extract out a region into a separate grant. The return value is as follows: (before, new split, after). Before and after may be None, which occurs when the split off region is at the start or end of the page respectively.

Panics

Panics if the start or end addresses of the region is not aligned to the page size. To round up the size to the nearest page size, use .round() on the region.

Also panics if the given region isn't completely contained within the grant. Use grant.intersect to find a sub-region that works.

DANGLING const

rust
const DANGLING : usize

Table struct

rust
struct Table { /* … */ }

AccessMode enum

rust
enum AccessMode {
    Read,
    Write,
    InstrFetch,
}

PfError enum

rust
enum PfError {
    Segv,
    Oom,
    NonfatalInternalError,
    RecursionLimitExceeded,
}

CowResult struct

rust
struct CowResult { /* … */ }

copy_frame_to_frame_directly fn

rust
unsafe fn copy_frame_to_frame_directly(dst : Frame, src : Frame)

try_correcting_page_tables fn

rust
fn try_correcting_page_tables(faulting_page : Page, access : AccessMode) -> Result<(), PfError>

MmapMode enum

rust
enum MmapMode {
    Cow,
    Shared,
}

BorrowedFmapSource struct

rust
struct BorrowedFmapSource { /* … */ }

handle_notify_files fn

rust
fn handle_notify_files(notify_files : Vec<UnmapResult>)

CopyMappingsMode enum

rust
enum CopyMappingsMode {
    Owned,
    Borrowed,
}

GenericFlusher trait

rust
trait GenericFlusher { /* … */ }

NopFlusher struct

rust
struct NopFlusher { /* … */ }

Flusher struct

rust
struct Flusher { /* … */ }

Released under the AWFixer Source Available License v0.4. #linuswasright