Skip to content

initramfs: release reserved page range after extract() copies into tmpfs #259

@sysheap

Description

@sysheap

At boot, the initrd's physical range is reserved in the page allocator so we don't hand those frames out for anything else:

  • Reservation: crates/kernel/src/lib.rs:134 (initrd_range passed to memory::init_page_allocator)
  • Consumption: crates/kernel/src/initramfs/mod.rsfind_initrd() turns the range into a &'static [u8] via ValidatedPtr::from_trusted, and extract() walks the cpio and writes every entry into the tmpfs-backed /.

Once extract() returns, the reserved bytes are dead — we've copied everything into tmpfs. For a ~5 MB rootfs.cpio that's ~5 MB of RAM held for the life of the kernel with no consumer.

Why deferred

PageAllocator (crates/mm/src/page_allocator.rs:219) currently exposes only alloc + dealloc. It has no `release_reserved(range)` API. Adding one safely needs:

  1. A way to convert a reserved range back into free-list pages, taking the allocator's lock.
  2. A lifetime / pointer-provenance argument that nobody still holds the &'static [u8] slice returned from find_initrd() once we release. Today that slice leaks out into extract() and is dropped when that fn returns, but a future refactor that stashes the bytes would silently race. Worth a note / test.

Flagged in the PR review for commit 6760dbd but deliberately not fixed there — this is "not broken, but arguably" territory and the fix is invasive enough to deserve its own changeset.

Rough plan

  1. Add `PageAllocator::release_reserved(range: Range<NonNull>)` (or equivalent) that splices the range into the allocator's free structure.
  2. At the call site in initramfs::extract(), after successful extraction, call the release API with the reserved range.
  3. Unit test: reserve a range, release it, alloc pages and verify the formerly-reserved frames are served.

Created by Claude Code

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions