Skip to content

feat(sched): the I/O-priority boost — COM2/IPC latency fix (ADR-0022 epic) - #225

Merged
NickFlach merged 1 commit into
mainfrom
feat/adr-0022-io-boost
Jul 15, 2026
Merged

feat(sched): the I/O-priority boost — COM2/IPC latency fix (ADR-0022 epic)#225
NickFlach merged 1 commit into
mainfrom
feat/adr-0022-io-boost

Conversation

@NickFlach

Copy link
Copy Markdown
Collaborator

Implements ADR-0022's deferred epic — the I/O-priority boost, the option table's principled fix. A process whose awaited I/O just arrived (IPC delivery to its mailbox, or a COM2 RX byte for the registered holder) is flagged io_boost and picked out of turn at the next reschedule — collapsing a hop from ~one round-robin rotation (~450ms) to tick-detect + one quantum remainder.

Measured result (WSL, gates armed in this PR)

before after
PING median ~0.45s 0.052s (~9×)
STATUS median ~0.90s 0.048s (~19×)

Every agent-facing MCP tool call (qos_status, qos_qpu_submit, attestation) rides this wire.

Design (hardened by a 4-lens adversarial panel: 31 findings — 7 blockers, 15 majors — all folded in)

  • Sticky 0xFF absent-device latch: an unbacked COM2 port reads all-ones — without it the boost would fire on every tick of every COM2-less boot (nearly the whole functional CI suite).
  • SCHED_BOOST_MAX_CONSEC=2 starvation guard: a boost ping-pong would otherwise monopolize every yield-path reschedule AND — by resetting the quantum counter — keep quantum expiry itself from firing, starving the roster invisibly to every liveness floor.
  • pick_next stays pure; the flag is consumed only at the dispatch COMMIT (it is a bare predicate in the CPUKILL pre-check and called twice on the kill path — a scan-side clear would eat boosts).
  • COM2 holder = (pid, generation) + live-cap validation at the boost site + cleared in process_destroy (a bare pid would boost whatever recycles it — the ADR-0023 lesson).
  • boost_count counts HONORED picks at the commit (a set-side counter is the switch_count vacuity trap); exposed as trailing boost= on SYSINFO_SCHED (prefix-safe).
  • ipc_send boost-set in its own irq bracket; default RR arm only (RESONANT/LOTTERY untouched); SCHED_IO_BOOST 0 restores the exact pre-epic pick behavior.

Gates re-armed in the same PR

  • ci-smoke-latency: PING median < 0.30s over n=9 (boost-off phase-locks to the full rotation ≥~0.45s on any host — fail-side structural) AND honored-boost delta > 0 (binds effect to mechanism; a bare median is gameable by a quantum change the sched gate deliberately tolerates). STATUS armed at < 0.6s with a 3-of-5 floor.
  • ci-smoke-sched: LOAD ping loop paced at fixed cadence (boost-invariant load profile) + armed max_gap ≤ 600 ticks starvation ceiling — the only metric that can referee the fairness guard.

Four-way verification (local WSL)

  • Boost ON: latency green (0.052s/0.048s, +24 boosts); sched green idle (199.9/1000t) + load (199.5, maxgap 45).
  • Boost OFF (SCHED_IO_BOOST 0): latency RED on both assertions (0.448s median — landing exactly on the predicted phase-locked floor — and +0 boosts); sched green (199.9 — the preempt band is structurally boost-invariant: the expiry increment precedes the pick).
  • Full make ci-smoke on the boost-on kernel: 65 SUCCESS gates, PASSED (including the ADR-0023 rebirth gates).

ADR-0022 updated: the deferred epic is implemented.

🤖 Generated with Claude Code

…epic)

The deferred principled fix from ADR-0022's option table: a process whose
awaited I/O just arrived (IPC delivery, or COM2 RX for the registered
holder) is flagged io_boost and picked out of turn at the next reschedule
— collapsing a hop from ~one round-robin rotation (~450ms at rest) to
tick-detect + one quantum remainder.

Hardened by a 4-lens adversarial design panel (31 findings: 7 blockers,
15 majors, all folded in):
- sticky 0xFF absent-device latch: an unbacked COM2 port reads all-ones,
  so without it the boost fires every tick of every COM2-less boot
  (nearly the whole functional CI suite)
- SCHED_BOOST_MAX_CONSEC=2: a boost ping-pong would monopolize every
  yield-path reschedule AND keep quantum expiry from ever firing —
  starving the roster invisibly to every liveness floor
- pick_next stays PURE (it is a bare predicate in the CPUKILL pre-check
  and called twice on the kill path); the flag is consumed only at the
  dispatch COMMIT in scheduler_reschedule/scheduler_kill_current
- COM2 holder registered as (pid, generation) + live-cap-validated at
  the boost site + cleared in process_destroy (a bare pid would boost
  whatever recycles it — the ADR-0023 lesson)
- boost_count counts HONORED picks at the commit (a set-side counter is
  the switch_count vacuity trap); exposed as trailing ' boost=' on the
  SYSINFO_SCHED line (prefix-safe for old parsers)
- ipc_send boost-set in its OWN irq bracket (it had none) for the
  documented IF=1 kernel-thread-sender pattern
- default round-robin arm only; RESONANT/LOTTERY untouched
- SCHED_IO_BOOST 0 restores the exact pre-epic pick behavior (the
  revert-confirm flag)

Gates re-armed in the same increment (the fix is only as real as they are):
- ci-smoke-latency: PING median < 0.30s over n=9 (boost-off phase-locks
  to the full rotation >=~0.45s on any host — fail-side structural) AND
  honored-boost delta > 0 (binds effect to mechanism; a bare median is
  gameable by a quantum change the sched gate deliberately tolerates);
  STATUS armed at < 0.6s median with a 3-of-5 success floor
- ci-smoke-sched: LOAD ping loop paced at fixed 0.5s cadence (boost-
  invariant load profile) + armed max_gap <= 600 ticks starvation
  ceiling — the only metric that can referee the boost's fairness guard

ADR-0022 updated: the deferred epic is implemented.

Co-Authored-By: Claude Fable 5 <[email protected]>
@NickFlach
NickFlach merged commit 9449ce6 into main Jul 15, 2026
25 checks passed
@NickFlach
NickFlach deleted the feat/adr-0022-io-boost branch July 15, 2026 03:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants