feat(mem): high-memory writeback proof + differential CI; ADR-0021 Accepted (PR-4) - #216
Merged
Merged
Conversation
…cepted (PR-4) Completes ADR-0021 (dynamic PMM sizing) and flips it to Accepted. Two new boot self-tests, wired after PMMCLAMP: - pmm_highmem_selftest (PMMHIGH): the load-bearing proof that dynamic sizing is SAFE above 128 MB. On RAM past 128 MB it allocates a top-of-pool frame, asserts the physical address is genuinely high (>= 128 MB, < 1 GB), then WRITES two distinct sentinels through the returned identity VA and reads them back -- so a boot.S that mapped only 128 MB (or a wrong/stale map) faults or mismatches here instead of silently handing out an unreachable frame. On the -m 128M leg there is no high frame, so it reports the SKIP branch (proving the guard ran, so the pass is not vacuous). - pmm_residency_storm_selftest (PMMSTORM): extends the single-shot heap reservation proof to a bulk drain -- 1024 frames pulled with the rover aimed straight at the reserved kernel heap, asserting none land in [__heap_start, __heap_end). Catches a multi-alloc rover regression the single-shot PMMHEAP check could miss. Differential CI legs `make ci-smoke-mem256` / `ci-smoke-mem512` (jobs pmm-differential-256/512, both gating release) boot at 256/512 MB and assert the frame count lands in that size's window (~0xFFE0 / ~0x1FFE0 -- it ~doubles / ~quadruples the 128M leg's 0x7FE0) AND that PMMHIGH took its live writeback branch. This is the true hardcode-vs-live differential the -m 128M leg cannot show: a 128 MB hardcode prints 0x8000 at every -m and never the live PMMHIGH. Revert-confirmed two ways: re-hardcoding memory_init to 128 MB reddens the mem256 sizing window (0x8000 outside [65280,65536]); broadening the high-memory guard so 256 MB wrongly skips reddens the mem256 PMMHIGH-live check while sizing still passes (the two gates are independent). Every "un-fakeable gate" named in the ADR-0021 design is now live. Build clean under -Werror; format/cppcheck/api-consistency green; ci.yml validated. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Final increment of ADR-0021 (dynamic PMM sizing) — flips the ADR to Accepted. Adds the load-bearing proof that dynamic sizing is safe above 128 MB, plus the differential CI that proves the sizing is live (tracks
-m), not a hardcode.New boot self-tests (
kernel/src/memory.c, wired afterPMMCLAMP)pmm_highmem_selftest(PMMHIGH) — on RAM past 128 MB, allocate a top-of-pool frame, assert its physical address is genuinely high (>= 128 MB,< 1 GB), then write two distinct sentinels through the returned identity VA and read them back. Aboot.Sthat mapped only 128 MB — or a wrong/stale map — faults or mismatches here instead of silently handing out an unreachable frame. On-m 128Mthere is no high frame, so it reports the skip branch (proving the guard ran — not a vacuous always-pass).pmm_residency_storm_selftest(PMMSTORM) — extends the single-shot heap-reservation proof to a bulk drain: 1024 frames pulled with the rover aimed straight at the reserved kernel heap, asserting none land in[__heap_start, __heap_end). Catches a multi-allocation rover regression the single-shotPMMHEAPcheck could miss.Differential CI legs
make ci-smoke-mem256/ci-smoke-mem512(jobspmm-differential-256/512, both gatingrelease) boot at 256/512 MB and assert:~0xFFE0/~0x1FFE0, i.e. it ~doubles / ~quadruples the 128M leg's0x7FE0; andPMMHIGHtook its live writeback branch.This is the true hardcode-vs-live differential the
-m 128Mleg alone cannot show: a 128 MB hardcode prints0x8000at every-mand never the livePMMHIGH.-m0x7FE00xFFE00x1FFE0Revert-confirmed (anti-vacuous, two independent teeth)
memory_initto 128 MB →mem256sizing window reddens (0x8000outside[65280,65536]).mem256PMMHIGH-live check reddens while sizing still passes (the two gates are independent).Every "un-fakeable gate" named in the ADR-0021 design section is now live.
Verification
-Werror;clang-format/cppcheck/check-api-consistency.shgreen;ci.ymlYAML validated.ci-smoke(128M),ci-smoke-mem256,ci-smoke-mem512all pass locally.🤖 Generated with Claude Code