Repository navigation
The inventory keeps its gaps once, by length, and inserts and removes in place - #1256
Conversation
… in place The free ranges were held twice: by start in one map and by length in a set, both rewritten on every insert and removal, though the entries already say where every gap is. Now only the set by `(length, start)` stays, the one placement needs; an insert or removal finds the gap or gaps it changes from the neighbouring entries. An insert joins the neighbours it continues directly, from the two lookups it makes anyway, rather than inserting and then walking every entry around the range; a removal takes its entries one at a time without first listing their starts. A map and unmap of one page so makes about half the tree lookups and one allocation where it made two. On the host (load average about 90, min of 300 batches), one page placed, inserted and removed in a space of 16 to 512 ranges: the insert path 116-176 ns to 50-82, the removal 148-177 to 105-145; allocations per pair 2 to 1. Driven with the inventory it replaces through 6,000,000 random changes, every answer and the whole state after each were equal; two seeded defects were caught. The mixed-load test now asks every placement's exact answer of a page map. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Review of 55fafd6What I read: the commit, ArchitectureThe owner is right and the representation is simpler. The by-start map repeated what the entries already say: the gap below an entry starts where the entry before it ends. Deleting the map removes a second index and the code that kept the two in step ( Invariants and complexity
Each operation keeps them:
As far as I can trace, it is correct. One check stays silent: the results of The differential's coverageIt is strong where it compares:
Where it is weaker:
The committed mixed-load test checks exact placements against a page map, an independent oracle, and caught both unit mutations. Overlap with #1223's records#1223's records commit adds the paragraph that puts 735 + 720 ns of the T14's FindingsBLOCKER
PR description (the orchestrator's to correct): "put a third of the T14's SUGGESTION
Evidence and metal
SEND BACK for the one fix. After it, the PR is LAND-pending-metal on the conditions above, and the queued A/B at 2bc40c8 still applies. |
…cord says where map/unmap's time went `range_heap` still charged each range for the by-start free map this PR deletes, and its comment named two indexes and two removal lists. It now charges a range's entry, its gap's place by length, and its share of the one list a removal gathers, at up to three times its length while that list doubles. The mixed-load test compares the free index with the page map's gaps exactly. #1223's paragraph putting the T14's `mem.map_unmap_4k` in the inventory moves here, with this PR's host split. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Re-review of 2b3d442Scope: whether round 1's findings are resolved, and whether the changed code is correct. What I read:
Round 1
FindingsNone. The changed code is correct. Evidence
Landing conditions
LAND, pending the guest run and metal above. |
With no bench booting, the record names the A/B on both benches that the single free index still owes, and what main must show in it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Problem
The 2026-11-11 stage probes put about 70% of the T14's
mem.map_unmap_4k(2,070 ns against Linux's 1,609) in the inventory: 735 ns to insert the page and 720 to remove it (evidence). The inventory kept its free ranges twice, by start in a map and by(length, start)in a set, and rewrote both on every change, though the entries already say where every gap is. An insert then joined neighbours by walking every entry around the range, and a removal listed the starts it would take in oneVecbefore collecting the entries in another.Change
(length, start), the order placement needs. An insert or removal finds the gaps it changes from the neighbouring entries.Vecit answers) where it made two.The contract is unchanged: same placements, same joins, same answers.
Checks
cargo test -p kernel --lib --features sched-check: 454 passed.cargo clippy -p kernel --lib --tests --features sched-checkon the host.cargo clippy -p kernelonx86_64-unknown-noneand onaarch64-unknown-none-softfloat.-D warnings.virt_smp,std_threads_count_the_cpus_and_give_back_ended_threadsanda_user_copy_faults_in_mid_copy_or_ends_as_bad_address. Every mapping in those boots goes through the new inventory, thread stacks are mapped and unmapped across CPUs, and a copy's buffer is unmapped under it. It is queued; 43081326308, at the measurement branch, is cancelled as not code-identical.issues/user-memory-hot-paths-are-slower-than-2-mib-pages.md. The benches are down, so it is not a landing condition: an A/B on both benches ofosbench_systemandosbench_mem, main from before and after. Main after must readmem.map_unmap_4kandmem.munmap_part.4kfaster, and no other row of the two groups slower.memperf-inv-ab2bc40c8 againstmemperf-ab-base8248c23) never booted.Records
mem.map_unmap_4kin the inventory is now this PR's, moved from An unmap walks no futex bucket while no thread of its space is in a futex wait #1223, with the host split and the owed A/B.Review r1 (2b3d442)
range_heapcharged each range for the deleted by-start map, and its comment named two indexes and two removal lists. It now charges the entry, the gap's place by length, and three times the range's place in the one list a removal gathers, its peak while doubling.cargo test -p kernel --lib --features sched-check(454 passed), and clippy on the host library with tests, onx86_64-unknown-noneand onaarch64-unknown-none-softfloat, with the adopted lints and-D warnings. Each exited 0 (logs).Not run, and why
cargo run -- --ci host: under the owner's testing policy only the touched crate's tests and lints run; the merge queue runs the rest.🤖 Generated with Claude Code