Repository navigation
Conversation
An empty commit that opens the design round for issues/placement-is-blind-to-caches-and-topology.md. The design and its roast are in the pull request's body; nothing is built until it is accepted, and the build round drops this commit. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Collaborator
Author
|
The research behind this design, kept where it cannot vanish: https://github.com/ToyOSOrg/evidence/tree/ff168419bb1759ba1fab983661e32fe70817199a/research. It holds one survey per area (fair model, topology and balancing, microsecond-scale allocation, real time, energy and capacity), this body as posted, and the two deleted ToyOS specs §3.6 builds on. |
Collaborator
Author
|
Design acceptance, recorded by the orchestrator for the owner. He was shown the staged design:
He answered "Accept, build in stages". Each stage is its own pull request, judged by its metal rows and kill conditions on both benches. The audio rows gate S2, S4 and S5. S0–S2 land before #865 lifts the CPU cap. |
Japabu
added a commit
that referenced
this pull request
Oct 12, 2026
…S3, the threshold-2 staging for S2 Review round 3 of #874. - a-woken-thread-waits-out-a-sibling-spinners-quantum-when-every-cpu-is-busy: the unstaged phase-2 halving and the AMD bench's phase-3 p99 from both metal judgements, and the T14's single 10 ms phase-5 wake, owned by stage S4 of #872 and exiting at its re-run of K1-K4, as the orchestrator's application of the owner's ruling (#885) orders. - a-wake-whose-waker-parks-next-is-forwarded-to-an-idle-cpu: the forward's cost on a synchronous wake, owned by S3, with spawn_cost's reading from the second judgement's readbacks. - the-work-conservation-cases-were-staged-for-a-push-threshold-of-two: the tightness half the topology suite lost, and group_imbalance's premise, owned by S2. - interactive-mix-crosses-the-fairness-bound-at-two-cpus: owned by S4, and its scratch test and output are linked where they are kept. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015xhaydXCVRNscoccHYFUWy
Japabu
added a commit
that referenced
this pull request
Oct 12, 2026
The busy-target kick's own-CPU arm set the poster's need_resched, so a futex_wake that woke tasks parked on the waker's CPU ran a pass before the syscall returned, placing each of them. On the T14 the 64-waiter wake_storm_cost walk read 132,867-153,899 cycles in the three boots that carried the kick against 52,910-74,328 in fifty without it, and round 3's boot crossed the row's linear bound (16 -> 64 waiters, 26,331 -> 132,867). On an 8-vCPU guest the storm syscall held about one such pass at 64 waiters and none with the kick reverted, and the pass's time went to the process's fair-share lock, which the storm's other waiters were taking as they re-parked. park::deliver now posts an ordinary wake whose target is the poster's own CPU without ringing: that CPU's own next pass drains it, as on main, and no edge stands with no pass owed to elide other CPUs' kicks to it. A boosted wake still rings and kicks. Kicker gains runs_on, which the kernel answers from its CPU id and the simulator from its poster. The wait this leaves a self-posted wake is filed for #872's S3: issues/an-ordinary-wake-posted-on-its-own-cpu-waits-for-that-cpus-next-pass.md. Two AMD-bench gaps the whole-suite run showed and nothing recorded are filed: issues/the-hard-lockup-detector-samples-no-amd-cpu.md and issues/no-watchdog-arms-on-an-amd-machine.md. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015xhaydXCVRNscoccHYFUWy
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.
Design round. Nothing is built. The branch holds one empty commit (
c7261039c) on177e72a9e. This body replaces the first design, which the owner sent back with the ruling "state of the art from the beginning. the best current scheduler theory has to offer." His earlier ruling on order stands (#865 (comment)): topology first, then #865 lifts the CPU cap. Everything below is the agent's design; the owner has ruled only on those two points.The design rests on five research surveys of primary sources: papers, specifications, maintainers' patches and design documents. Every claim from a source carries its URL and a tag:
No choice below is made because another system makes it. Where Linux appears, it appears as a measurement or a failure, not as a precedent.
1. The scheduler at
177e72a9e, and what it costskernel/pure/sched/fair.rs,queue.rs) works as follows:Frontierisfetch_maxed on every pick (fair.rs:29,cpu.rs:1827).fair.rs:13). The quantum is a fixed 10 ms (fair.rs:16).kernel/sim/tests/policy.rs:399).issues/granularity-bound-crossed-at-four-widths.md).Frontieris a line every CPU writes on every pick. A line hop measured 100–101 ns on the T14 (issues: the kernel performance audit's findings, priced by three scouts, and the speed track restaged by them #866 (comment)).task.rs:686,pipe.rs:120). Its measured cost is 93.3 ms of audio starvation behind a fair storm (issues/cpu-time-is-a-band-and-not-a-reservation.md).idle_sibling(cpu.rs:916),best_victim(:2082),push_on_surplus(:2105) andCpuHandles::place(:2332). A wake goes to the CPU the task parked on (park.rs:109-128).2. What the research settles
3. The design
The frame has two parts:
Every documented failure in §2's locality rows is a hint that broke the core.
3.1 Topology: the machine's cache tree, with capacity carried as data (stage S1)
x2apic_id >> ceil_log2(sharing). That covers the LLC, plus an Intel E-core module's shared L2 where one exists.IA32_HWP_CAPABILITIEShighest performance, an MSR the kernel already programs, or AMD's CPPC MSR where the part has one.lib/acpigives the processor hierarchy and the cache owned by each node. The MADT GICC gives each CPU's efficiency class.capacityis 0..1024 against the fastest CPU;efficiency_classis ordinal; the core kind is opaque.kernel/pure/sched/topology.rs, host-tested. The x86 word decoding is pure arithmetic over recorded CPUID words; onlycpuidandrdmsrstay inarch.topo: cpuN core=… llc=… pkg=… cap=… class=….3.2 Work conservation is the invariant every placement rule answers to (S0, S2)
WC. A CPU that is parked, with no probe outstanding and nothing in flight to it, never coexists with a stealable task that has waited longer than the patience of the level between them, unless that task's CPU has rung a parked CPU for it or published it in a summary the parked CPU re-read after parking.
Bounded response. An idle CPU that can see stealable work runs a task within K protocol rounds. K is derived from the tree's depth.
sched-checkkernel monitors it on idle CPUs, so the monitor is charged to idle time.3.3 Placement and balancing (S2)
stealable, the eligible fair tasks queued other than the loaded one (A wake to another CPU that is busy is drained at its next preemption point and runs within a bound #874's count); and its last-busy stamp. Σw joins in S4.balance_fenceDekker pair, widened from one word to two.loom_push.rsmodels the pair, and its relaxed-fence control must still turn red.cpu.rs:1838-1880's rule, kept).stealable > 0rings one parked CPU, nearest first: a parked whole core in its LLC, then any parked CPU there, then another LLC after its patience. The two-choice rule picks among candidates, and the rung CPU pulls, so binding happens late.ROTATE(driver.rs:388) goes: two random choices already break the boot tie.3.4 The wake path, and what becomes of #874
The parked record is the home CPU's, so home decides at its drain, as #874 accepted. The order is:
idle_near(home)picks a whole idle core in home's LLC, else any idle CPU in it, with one word read. Thenhand_off, which is A wake to another CPU that is busy is drained at its next preemption point and runs within a bound #874's forward.last_waker(record-local, no new shared word), moves to an idle CPU in the waker's LLC. Row R3 judges it.#874 is kept, lands first, and stays the wake path's "whether and when".
PUSH_THRESHOLD = 1) stand unchanged.idle_nearin S2. The body ofidle_siblingis the only thing replaced.The sync handoff is recorded, not designed. Moving a wakee onto the waker's CPU when the waker is about to block needs a "the caller now waits" signal. ToyOS's IPC (framed pipes and ports, no call/reply primitive) does not carry one.
3.5 The fair model: EEVDF on each CPU (S4)
i128without a division.Frontier, the global line written on every pick.Adoptand places at V_dst − lag·(W+w)/W. A move is the scheduler's act, not the task's, so it neither gains nor loses. An ineligible task is never migrated.issues/the-fair-band-orders-by-share-alone-and-a-woken-editor-waits.md).Frontier, the per-processShareStatepot and its lag,MAX_VRUNTIME_LAG_NS, and the frozen insertion-time keys behind I5's staleness term. It closes the mechanism ofissues/per-process-fair-split-is-the-policy.mdand the defect inissues/granularity-bound-crossed-at-four-widths.md.3.6 Real time: reservations held as capabilities (S5)
This is
issues/cpu-time-is-a-band-and-not-a-reservation.md's track. Its structure stands:The research amends it in six places:
supervisorholds the root bandwidth and endows it fromsystem.toml.Rights::RTandSYS_RT_ENTER.pipe.rs:120,RtState::inherited, invariant I9) and the mark's soundd-to-client trigger. The mark stays only for lock waits.3.7 Energy and capacity
3.8 Refused, with the reason
kernel/CLAUDE.md).4. What it deletes
idle_sibling;best_victim,push_on_surplus(withpush_cursor) andCpuHandles::place;ROTATE;Frontier;ShareStatepot and its lag;MAX_VRUNTIME_LAG_NS;QUANTUM_NSas the fairness granularity, which becomes r_max;serves_rt_band;RtState::inherited,lends, invariant I9) andrt_boost_pending;DYING_AGE_NS,DYING_CHUNK_NS,aged_grant,Corpse::since);Rights::RTandSYS_RT_ENTER.placement-is-blind-to-caches-and-topologyat S3;the-fair-band-orders-by-share-alone-and-a-woken-editor-waitsandgranularity-bound-crossed-at-four-widthsat S4, andi13s-margin-at-32-cpus-is-down-to-two-millisecondsre-measured against S4's new bound;cpu-time-is-a-band-and-not-a-reservationat S5.5. Stages, and how each is verified
The order is the owner's: S0–S2 before #865, then S3. S4 and S5 are independent tracks:
Every metal row runs on both benches. Its negative control is the whole change reverted onto the base its green arm was measured on. The tiers are host first, then simulator, then metal; QEMU is not used.
from_keys.idle_near.S4's simulator gates. These are the paper's theorems run as invariants:
S4's independent oracle is a fluid GPS model and a separately written WF2Q+, fed identical traces: a differential implementation.
The metal rows and their kill conditions (9 boots per arm where a rate is compared):
topology_readbacktopo:lines against an expectation derived from the scout's raw words. The independent oracle is a userland program's own CPUID.smt_spreadwake_storm_cost, the audio rows.The audio rows (
audio_tone_load's underruns stay 0 under burners) run at S2, S4 and S5. Under the root rule on audible quality, any red there stops the stage.6. The owner's question: should the simulator model topology first? Yes, as S0, and only its shape
Scenario::with_topologybuilds per-CPU keys for any tree, under a seeded permutation of dense ids. The keys go through the sameTopology::from_keysthe kernel uses.policy.rs) is exactly what a reordered scan can break.policy.rs's header).7. How it fits #865's boot-sized tables
[T; MAX_CPUS]static is added.Topology(each level's domain lists), the per-LLC summary lines (one padded word per 64 members) and the machine bitmap (one word per 64 LLCs) areBox<[_]>s built once, after the roster commits, indriver::init, besideCpuHandles. Nothing namesMAX_CPUS.8. The roast
virtmachine provide them is unmeasured; it is the first step of S1's build. Where QEMU lacks them, the invocation changes or the gap is filed.9. Unsure
amd-pstate's documentation, the CPPC registers are MSRs only on some Zen 3 and later parts; others reach them through_CPC, which is AML. So the AMD bench may read "unknown" until the AML track lands.driver::initruns before every chooser on the BSP. This is carried over from the first design, and I have not traced it.Gates
None run. The branch holds one empty commit and changes no file.
🤖 Generated with Claude Code
https://claude.ai/code/session_015xhaydXCVRNscoccHYFUWy