diff options
| author | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-10-15 18:01:46 -0400 |
|---|---|---|
| committer | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-10-15 18:01:46 -0400 |
| commit | 99e5a61e87b34416259254c22241a072fbd412a4 (patch) | |
| tree | 46fe6f4da53045ecc385b52728f80ed7923750fe | |
| parent | ecfb1278086f98161402f93bca8d3df602fbcb45 (diff) | |
| download | open-iov-99e5a61e87b34416259254c22241a072fbd412a4.tar.gz open-iov-99e5a61e87b34416259254c22241a072fbd412a4.zip | |
lottery: offline analysis report - engine-lottery root cause ranked, fail-closed rejected
LOTTERY-REPORT.md: live r155 evidence (streams2 bad=32768 with qmd_rel=6
and 0/205 on all attempts; 98 never-attempted captures soft-released during
the vecadd burst), the exact retry/failure chain, the proven unsoundness of
the F1 fail-closed release (idempotent repeats show 0/205 with correct
data), ranked fix proposals (defer busy refusals, 4-bank win0 + qmdwin
double-buffer, warm sem push, sound-discriminator hunt), and the stall
class characterization. No kernel changes; the rejected gate attempt is
preserved on branch lottery-m156-gate-attempt.
| -rw-r--r-- | LOTTERY-REPORT.md | 355 |
1 files changed, 355 insertions, 0 deletions
diff --git a/LOTTERY-REPORT.md b/LOTTERY-REPORT.md new file mode 100644 index 0000000..70529a5 --- /dev/null +++ b/LOTTERY-REPORT.md @@ -0,0 +1,355 @@ +# LOTTERY-REPORT — per-boot engine lottery (`ecfb1278` baseline, r155 live) + +* Offline analysis + implementation attempt. Worktree: `/home/rmcore/Git/integdev_gpu_drv/open-iov-lottery` + (branch `lottery`, based on `ecfb1278`). No module load, no QEMU/mdev/GPU/guest writes, no reboots. + Build verified: `cd kernel && make -j8` (kernel 6.8.0-147; note: this worktree has no + `nvidia-open-gpu-kernel-modules` submodule, so the build needs `KBUILD_EXTRA_SYMBOLS=` on the command + line to reach modpost; the plain `make -j8` failed only on that missing file). +* Primary live evidence: `/tmp/opencode/dmesg-follow-r155.log` (read-only) and its client outputs in + `/tmp/opencode/soak-20261015-172722/` + `/tmp/opencode/r155-*.log`. +* Prior reports: `analysis-2026-10-14b/AGENT-C-engine-allwrong-analysis.md`, + `analysis-2026-10-15/AGENT-bigcopy-analysis.md`. +* **Branch state: no fix committed.** An F1-style fail-closed release gate was implemented, then + reverted after its decisive unsoundness was proven against the live log (finding F4). The two commits + are preserved on local branch `lottery-m156-gate-attempt` (`de91d640`, `eee92231`); `lottery` is clean + at `ecfb1278`. + +--- + +## 1. Top findings (ranked) + +### F1 — PROVEN: the engine's completion ack (`qmd_rel`) is a front-end retirement, not an execution +witness; the host returns success on it and the client reads wrong data. + +Live, this boot, single client, end to end (`dmesg-follow-r155.log`): + +| line | event | +|---|---| +| 27847 | `launch captured h=0x5c00001f push=0x2008002cc … rel=0x204027c7c/6` (streams2 launch) | +| 28163 | `GR LAUNCH submitted … qmdwin=0x107000` (1044.568) | +| 28216 | `output retirement wait: 0/205 pages changed after 720 ms (no writes)` | +| 28440 | `0/205 …` after outcome retry 1 | +| 28493 | `0/205 …` after outcome retry 2 | +| 28564 | `0/205 …` after outcome retry 3 | +| 28576 | **`GUEST GR LAUNCH OK … qmd_rel=0x00000006 ch_rel=0xc0ffee02 elapsed_ms=3370 ok=8`** | +| soak `out-r1-streams2.txt` | **`STREAMS n=32768 bad=32768` / `STATUS FAIL`** (all-zero output) | + +The release word at `0x204027c7c` could not have been host-authored before 28576 (the hold's software +release runs only after the work item returns at 28576; `svc_gr_sw_release` is at +`gsp_sema_service.c:11388`, called from the hold resolution `:11754`/`:11768`), so the `qmd_rel=6` +that broke the poll was **hardware-authored with zero SM writes**. Same signature in r152 longevity +(matmul `bad=65536`, `0/205` after 725 ms) and r150 (`AGENT-bigcopy` M1). Code path: +`gsp_phys_booter.c:18564` returns 0; `gsp_sema_service.c:12031-12050` (`hw_rc=0`), `:11768` applies +the (no-op) release. + +### F2 — PROVEN: three distinct host paths author client-visible releases for launches nothing executed. + +1. **Acked-no-write** — `gsp_phys_booter.c:18388-18454` retries, then accepts at `:18564` (`ret=0`) + with the retirement wait observed `wrote==0`; the hold's success edge (`gsp_sema_service.c:11767-11768`) + then applies the completion release. Client proceeds with stale/zero output. (F1's path.) +2. **Timeout / no ack** — `gsp_phys_booter.c:18005-18072` returns `-ETIMEDOUT`; the sema hold's failure + branch (`gsp_sema_service.c:11736-11758` → `svc_fwd_hold_gr_release` :11409 → `svc_gr_sw_release` + :11388) authors the completion in software. This is AGENT-bigcopy M1 (r150 `memcpy_roundtrip` + `bad=10485760 csum=0`). +3. **Refused capture (never even attempted)** — `gsp_sema_service.c:14321-14375`: when a GR capture + cannot queue (`svc_gr_request` refuses while a hold is active, `:12958-12963`), the entry loop + *consumes* the push and soft-authors its completion at **`:14369-14374`**. Live: during ok=7's + 14.8 s backend saga the vecadd_loop burst produced **98 such releases with zero execution attempts** + (`work_guard … direct=99 gr_sw_rel=98`, log:22599; `rel-hold direct … (no work)` + + `GR launch release software-applied` pairs at log:20589-21255+). Those results were correct only + because vecadd_loop repeats an idempotent kernel; for a non-idempotent multi-launch client this is a + silent-zero factory. + +### F3 — PROVEN: the zero-write witness cannot distinguish no-execute from an identical rewrite, so +F1's proposed fail-closed release is **unsound** and was reverted. + +`vecadd_loop` launches 2..100 are the *same* `c = a + b` over the same buffers. At ok=7 (launch 2) the +post-run window dump shows the output already holding the result **before** the copy-out: + +``` +log:22613 window[64] reloc=0x150000 first=00000000 3f400000 3fc00000 40100000 changed=0 +log:20100 window[64] reloc=0x150000 first=00000000 3f400000 3fc00000 40100000 changed=1 (launch 1) +``` +`0x3f400000/0x3fc00000/0x40100000` = 0.75/1.5/2.25 = `a+b` for the first elements. An executed +identical rewrite writes the same bytes → `0/205 changed`; a no-execute also gives `0/205`. Both are +indistinguishable, and for the identical case the data is **already correct**. A gate that fails a +launch on `0/205` would have converted currently-green clients (`vecadd_loop` repeats, smiley passes +2..4 with identical tuples per AGENT-C §3, repeated matmul runs) into client-visible errors on correct +data. `smiley`/`matmul` repeats have the same property. This was not considered by AGENT-bigcopy F1 +(which reasoned about read-only kernels only); it is the reason no fail-closed release was landed. + +### F4 — PROVEN: the no-execute state starts at one launch and then persists module-wide for the boot. + +r155 sequence (all lines in the live log): + +``` +20280 908.833 GR LAUNCH submitted h=0x5c000019 push=0x20043c19c slot=0 (vecadd launch 2) +20281 908.886 sked rec +5ms cwd0=00012480 act=a0000005 grfifo=10100001 fecs_cur=b0143808 (enqueued, ctx loaded) +20338 913.840 GR LAUNCH FAILED timeout after 5000 ms (qmd_rel=0x5 …) (no retirement) +20389 914.004 sked rec +435ms cwd0=00002080 act=0 fecs_cur=0 (context saved/unloaded after the timeout) +20537 919.115 retry 1/3: fresh ring entry slot=1 published + rescheduled +20538 919.115 sked rec cwd0=00012480 … fecs_cur=b0143808 act=0 (re-enqueued + ctx reloaded, still no dispatch) +20543 919.836 output retirement wait: 0/205 pages changed (no writes) +… (outcome retries 2,3 with the m155 lane-tail rearm each time: #1059/#1061 accepted, #1063 0x1f; + firmware asserts 0x5294444 + FECS_A/B + 0x52c1504 accompany the tail: log:919.03-920.69) +22621 923.503 GUEST GR LAUNCH OK … qmd_rel=6 wrote=0 +… every later launch (including streams2 on a different channel h=0x5c00001f, 2 min later) never executes. +``` + +* The FECS save/unload at 914.0 is a **consequence** of the 5 s timeout + rearm, not the trigger: + ok=7 was enqueued with the context loaded at +5 ms and sat un-dispatched for 5 s first. +* **m155's lane-enable rearm does not revive dispatch** (first live test — it fires here; the context + reloads at 919.115, `act=0`, still no writes; r154's conclusion therefore still stands). +* Post-OK `CWD_T0=0x12480` is **not** a discriminator: it also appears for the good launches ok=1, + ok=2, ok=3, ok=5, ok=6 (log:7903, 8126, 12229, 16380, 20106). No proven register signature yet + (seen only 5 `sked rec` rows/boot). + +### F5 — HYPOTHESIS (ranked) for the ok=7 transition; each is a one-variable experiment. + +1. **Single-buffered QMD window.** `GSP_PHYS_RMCALL_VA_GR_QMDWIN` (`gsp_phys_booter.c:1063`) is *one* + page (0x107000, planted `:9565-9595`, prewritten every launch `:17711-17721`, published `:17802`). + The two-bank win0 rotation (754bbbe8) protects the win0 pool but not this page, which is rewritten + every launch while the previous launch's QMD-unit/look-ahead reads of the same VA may still be in + flight (the exact rationale the m151 comment gives for the win0 banks). **Ok=7 is the first launch + that reuses a win0 bank too** (`rmcall_gr_shadow_win0_used = (epoch&1)*8`, `:17038-17042`), i.e. the + first launch after the transition point where any pool VA is re-used. +2. **2-bank win0 is too shallow** — bank reuse happens every 2 launches; the handoff's lead (b) (4-bank) + mitigates and can be extended cheaply (pool VA space 0x1e0000..0x1effff). +3. **Engine-side stale const/PTE line for the win0 data path** (AGENT-C H1, m132/m133 precedent): the + M151 pre/post hashes show host pages identical, so any such staleness is engine-side; the two-bank + rotation is the only current mitigation. +4. Not supported by this log: m152 scratch-pool exhaustion (0 `launch refused` this boot), alias-cache + line reuse (the cache is HPA-keyed and never rewrites), constant-bank fill gaps (pre/post hashes + equal), PTE-line caching for the win0 line (planted pre-boot; m132/m133 unchanged). + +### F6 — PROVEN (ops): the soak's green is not an execution witness for repeated launches. + +`vecadd_loop`'s `VERIFY bad=0` passes because `c` was already correct after launch 1, even though +launches 2..100 were never executed (F2.3: 98 soft releases). Do not use vecadd_loop/soak green as +evidence that the forward path ran; use `output retirement wait` + `window[…] changed=` and the client's +own first-touch buffers (streams2/matmul). + +--- + +## 2. Q1 — What a good boot has that a bad boot lacks + +**It is not a boot property; it is a transition at one launch, after which every GR launch fails for the +rest of the boot (F4).** The checked candidates: + +| Candidate | Evidence | Verdict | +|---|---|---| +| SKED CWD allocation | Post-state `CWD_T0=0x12480` is identical for good ok=1/2/3/5/6 and bad ok=7/8 (log:7903…28576) | not discriminating | +| FECS context load | bad attempt at 908.885: `fecs_cur=b0143808` (VALID=1, loaded) for 5 s while `act=0`; the save at 914.0 follows the timeout | not the trigger | +| Channel scheduling state after m155 lane-tail | m155 replays #1059/#1061/#1063 + schedules + doorbell; context reloads (919.115) but `act=0`, 0 writes on all 4 attempts | re-arm insufficient | +| win0 bank alternating | 2 banks ⇒ reuse every 2 launches; ok=7 is the first reuse (epoch parity) | suspect (F5.1/2) | +| PTE fetch-line caching | win0/bounce lines planted at stage 3, never rewritten (`pdb_build` :9565-9700); m132/m133 fixed the only observed line issue | no new evidence | +| alias-cache line reuse (m152) | HPA-keyed, `line_out=~0` prevents extension; 0 `launch refused`, pool capacity 2048 (`guest scratch PT built … capacity=2048` at boot) | refuted this boot | +| constant-bank fills | `win0 param hash pre==post` and `guest-param hash pre==post` (e.g. log:22619-22620) | host-side verified | +| m152 scratch pool state | 0 refusals in r154/r155 (`launch refused`=0 in both handoff counts and this log) | refuted | + +--- + +## 3. Q2 — The exact retry chain and its client-visible outcome + +Attempt flow in `gsp_phys_backend_guest_gr_submit` (`gsp_phys_booter.c:16924`): + +1. `release0` selection `:17053-17104` — either a Tier-2 shadow alias of the guest release page + (engine writes the client's counter directly) or the module sem. +2. Copy-in `:17778-17800` (pre-doorbell, m142), publish `:17802`, poll `:17948`. +3. **Timeout branch `:18005`**: log `GR LAUNCH FAILED: timeout after 5000 ms (qmd_rel=… want=…)`; + - one re-arm `:18015-18033` (`gsp_phys_rmcall_gr_resched_locked` `:16737-16784` — m155 adds the + mode-35 lane-enable tail at `:16756`, then GPFIFO_SCHEDULE + TSG + doorbell), re-poll 5 s; + - up to `GSP_PHYS_RMCALL_GR_ATTEMPTS`=3 fresh-entry retries (`:18044-18072`, 2 s poll each); + - then the post-mortem block (`:18095-18353`) and `ret=-ETIMEDOUT` (`:18355`). +4. **Success branch**: `gsp_phys_gr_output_retire_wait` (`:16824-16888`) — whole resolved-page window, + adaptive exits (all changed / settled 3 polls / no writes 600 ms / 1.5 s cap). On `wrote==0`, + `gsp_phys_rmcall_gr_nowrite_retry` (`:18388-18454`) refills the bounce from the guest (`:16897-16922`), + re-publishes a fresh ring entry, reschedules and re-waits ≤3 times (shared attempt budget). + Then copy-out (`:18461-18538`, writes the window back regardless of writes) and **`ret=0`, + `GUEST GR LAUNCH OK` at `:18564`**. + +Client-visible outcomes: + +* **After 3 outcome retries with `wrote==0`**: still success. The hold's success edge + (`gsp_sema_service.c:11767-11768`) applies the (no-op if the engine acked) completion; the client + proceeds and reads whatever the window holds — zeros/stale for never-written outputs (F1), correct + for idempotent repeats (F3). +* **After the timeout path exhausts attempts**: `-ETIMEDOUT` → `svc_gr_req_bridge_fallback` + (`:12902-12920`, no-op when `cuda_bridge=0`) → the hold failure branch (`:11736-11758`) applies the + recorded releases **and** `svc_fwd_hold_gr_release` (`:11409`) authors the launch completion in + software (`svc_gr_sw_release` `:11388`). Client proceeds with stale/zero data (r150 `bad=10485760`). +* **Hold expiry backstop**: `SVC_FWD_GR_HOLD_TIMEOUT_MS` = 12 s (`:10909`), checked at `:11419-11426` + from `svc_fwd_hold_expire_check` (`:11610-11668`). Note this is *shorter* than the backend's worst + case (5+5+3×2 s + waits ≈ 26 s): an expired hold resolves mid-flight with the software release + (`:11649`), another fail-open edge. +* **Never-queued captures**: soft release at `:14369-14374` (F2.3). + +--- + +## 4. Q3 — Ranked fix proposals (with soundness assessment) + +### R1 (recommended first): defer "backend busy" refusals instead of soft-releasing them. + +* **Where**: `gsp_sema_service.c:14274-14293` (the m150 bounded retry-hold) and `:14321-14375`. + When `svc_gr_request` refused because `svc_fwd_hold.active`/INFLIGHT (i.e. the launch *could* run + later), leave the entry unconsumed (no GP_GET write) under the same bounded window as the m150 + `svc_gr_data_stalled` path, instead of consuming it and authoring the release. +* **Why sound**: the capture is not executed by anything today; deferring gives it a real attempt when + the backend frees, and the release stops being a lie. No false positives (only client latency, + bounded by the window). This closes F2.3 — the 98-release burst. +* **Risk/needs**: pump re-capture cost and interaction with the defer/release machinery need a live + cycle; `svc_gr_data_stalled`'s one-shot-per-entry window is the proven shape. + +### R2: win0 4-bank + QMD-window double-buffer (isolation hardening; two commits). + +* win0: grow `GSP_PHYS_RMCALL_GR_SHADOW0_SLOTS` 16→32 (VA 0x1e0000..0x1effff is free; static asserts at + `:2330-2346` must be extended) and select `(epoch & 3)` banks in `:17035-17042`. +* qmdwin: plant a second page at the freed old-win0 slot 0x108 (same 128 B PT line as 0x107; the line + is written once at stage 3, `:9565-9595`) and alternate `qmd_dst` by epoch in `:17602-17615`. + Rationale: the qmdwin page is prewritten every launch while the previous launch's reads of the same + VA may be in flight (F5.1). +* **Why**: either pool being re-used while reads are in flight is the best-supported remaining + host-side mechanism (F5); both changes are strictly additive isolation and cannot make a dispatch + worse. Correctness is conditional on the mechanism existing — validate with the F4 timeline. + +### R3: try the `cuda_bridge=1` fallback operationally while R1/R2 land. + +* `svc_gr_req_bridge_fallback` (`gsp_sema_service.c:12902-12920`) exists and is the designed order + (`:11888-11890`); with the bridge on, a lost forward is executed on the host GPU instead of being + soft-released (`:14366-14367` documents the bridge owning the release). This is not a kernel change + (one insmod flag) and directly converts the lottery into correct results for the affected launches. + +### R4: warm sem push in the outcome-retry path (experiment; the handoff's own lead). + +* **Where**: `gsp_phys_booter.c:18388-18454`, call `gsp_phys_rmcall_gr_sem_push_locked` + (`:14801-14877`) once before the first re-publish of a zero-write retry (bounded by its 5 s poll). +* **Why**: if the GR engine can still execute the known-good stage-4 semaphore block, the channel's + dispatch state is alive and the launch retry has a chance; if the sem push times out, the engine is + wedged and the launch is unsalvageable (fail fast instead of 4 futile attempts). + Efficacy unknown — it is a diagnostic *and* a possible revive lever; needs one cycle. + +### R5: fail-closed release — REJECTED as specified; only sound with write-provenance. + +AGENT-bigcopy F1 (withhold the completion release for unwitnessed data-bearing launches) was +implemented and then reverted (F3). A sound variant needs per-page write provenance: mark a guest data +page "engine-authored" when a retirement wait observes a change on it, invalidate on host-visible CE +software copies, and fail-close only launches whose *entire* data set is unprovenanced. Even that has +corners (guest CPU writes to sysmem operands, idempotent after CE rewrite); it is a design, not a +minimal fix, and must be evaluated on its own. The disabled attempt lives on +`lottery-m156-gate-attempt` for reference. + +### R6: find a *sound* execution discriminator, then gate on it. + +Before any fail-closed ships, establish a signature that separates executed-but-idempotent from +not-executed. Candidates to sample during the retire wait (1-2 ms cadence, `gr_skedrec`-style): +`PGRAPH_STATUS` (0x400500-class), `SKED_ACTIVITY`, `GRFIFO` GET/PUT, `CWD_T0`, `FECS_CTXSW_STATUS`, +plus the TPC exception latches. If a signature exists, it enables both a targeted re-arm and a sound +fail-closed (fail only the provably-not-executed non-idempotent launches... still ambiguous for +idempotent, but the *provably wedged* state lets the host avoid pretending success at the sema layer +where the client's data may be wrong). + +--- + +## 5. Q4 — Stalls + +### Userspace-spin class (r153 matmul 50-min spin; fixed by m154) + +* **Mechanism (proven, `e07c62b1`)**: the guest scanner's merged CE window covered a live CE channel's + GPFIFO ring VA (0x121010000); injected pins take precedence in the ring read path, so the ring read + the wrong PA (all-zero entry), the entry was silently consumed and the pool release was never + authored → client spins in userspace forever. +* **Fix**: `svc_va_hits_chan_ring` (`gsp_sema_service.c:15424-15451`) drops injected pins inside any + live channel's ring range in `svc_handle_map_add` (`:15492-15501`), counted + logged (first 8). +* **Coverage**: live in r155 — one drop fired (`log:23300 injected pin va=0x121011000 DROPPED`), + 0 in r154. The class is armed and observed; keep it. +* **r154 r2 smiley 400 s timeout (`rc=124`, un-diagnosed)**: ran *with* m154 and 0 `DROPPED` lines, so + it is not that collision. Residual userspace-spin families that remain: (a) a different translation + shadowing a release slot (demand pins vs scanner races), (b) a hold window that expires without an + author (the 12 s GR hold vs 26 s backend worst case, §3), (c) CE resolution latency (the scanner's + kprobe-gated chain discovery 35-90 s class — r147 recovered after ~90 s; a >400 s instance would + time out the client). Detection: `rc=124` + no `STATUS` line + frozen push counters. Forensics: + guest `wchan`/syscall of the spinning thread, `pushes`/`crel` counters in the sema summary, + `stalled VA` list, `DROPPED` count, and the hold lines (`rel-hold direct`, `GR launch release + software-applied`) around the client's start. No fix exists yet; capture the next occurrence early. + +### Cold-context first-launch timeout + +* **Mechanism**: the first launch after the engine context is cold (client start or after a save) + enqueues to SKED but `qmd_rel` sticks at 5 (schedule/fetch ack; no retirement). r155 ok=4 is the + textbook recovery: `GR LAUNCH FAILED` at +5 s → m155 rearm → `GR LAUNCH FAILED` at +10 s → + `retry 1/3: fresh ring entry` → executed within 18 ms (`log:15999/16124/16175/16177/16189`, + `elapsed_ms=10385`). The good retry state shows `cwd0=00002480 grfifo=02020001 fecs_cur=30143808` + (`log:16176`) vs the wedged `cwd0=00012480 grfifo=00000001 act=0` (F4) — a promising discriminator + to sample deliberately (R6). +* **Coverage**: the transient variant is recovered by m142 (re-arm) + 6b090f70 (fresh-entry retry) + + m155 (lane tail) — cost ~10 s per cold first launch. The **persistent variant** (F4: the same + channel/boot never dispatches again) is *not* recovered by any current mechanism; it is the same + state as the "engine lottery" no-execute and is what produces F1's silent zeros. + +--- + +## 6. Proposed live experiments (one variable each) + dmesg lines to watch + +All runs on a fresh module load per the campaign's normal cycle; keep `cuda_bridge=0` unless the +experiment says otherwise. Always `sudo dmesg -w` follower. + +**E1 — F4 trigger isolation (no code change).** Run the exact r155 order +(`mail → vecadd_loop → streams2`) plus `smiley`. Watch, per launch: +`GR LAUNCH submitted`, `sked rec +Xms cwd0=… act=… grfifo=… fecs_cur=…`, +`output retirement wait: N/205 pages changed after T ms…`, `window[N] reloc=… changed=`, +`GUEST GR LAUNCH OK …`, `GR LAUNCH FAILED: timeout…`, `retry N/3: fresh ring entry`. +Decision: if the first `0/205` launch is again the first *bank-reuse* launch (check the +`qmd_word … page copied to window-0 shadow VA=0x1eX000` lines' slot sequence), F5.1/2 rises. + +**E2 — 4-bank win0 only (one commit).** §4 R2a. Watch: the first `0/205` should move to the first +reuse depth ≥4 (or disappear); `win0 param hash pre==post`, `window[…] changed=` for the executed +first-touch launch (`matmul C`/`smiley`), and `GUEST GR LAUNCH OK` with `changed>0`. + +**E3 — QMD-window double-buffer (one commit, after E2).** §4 R2b. Watch the same lines plus +`qmdwin: relocating inline-QMD dest 0x…` (should alternate 0x107000/0x108000 per launch). + +**E4 — defer busy refusals (one commit).** §4 R1. Watch: +`GR launch release software-applied` and `rel-hold direct … (no work)` counts must collapse; +`GR LAUNCH submitted` count for a 100-launch client must approach 100; the client's completion latency +must stay bounded. Falsifier: a capture whose entry is re-captured forever (GP_GET not advancing) or a +client exceeding its timeout. + +**E5 — warm sem push on zero-write retry (one commit).** §4 R4. Watch on the first `0/205`: +`REAL GR SEM OK sem=0xc0ffee01` (engine alive) vs `REAL GR SEM FAILED: no release within 5000 ms` +(wedged); then whether the following `outcome retry N done: engine wrote U page(s)` becomes `U>0`. + +**E6 — register-signature hunt (instrumentation only).** Sample the F4/R6 register set at ~2 ms during +every retire wait and log on change, for a full boot. Compare `wrote==0` (and the F3-verified +idempotent launches) against `wrote>0`. Only if a signature separates executed-idempotent from +wedged does fail-closed (or a targeted re-arm) become sound. + +**E7 — bridge fallback A/B (flag only).** `cuda_bridge=1` for one cycle: all F2 outcomes should become +correct results (bridge authors data), at the cost of host-GPU execution. Watch `fwd_gr_bridge`, +`bridge` launch lines, and the client verifications (streams2/matmul/smiley first-touch clients). + +--- + +## 7. Proven vs hypothesis + +**Proven (evidence cited):** +1. `qmd_rel`/`ch_rel` are hardware-authored without SM execution in the failing class; the backend + returns `ret=0` (F1). +2. Three host paths author releases without an execution witness (F2); 98 releases in the r155 burst. +3. Zero-write fail-closed is unsound for idempotent repeats (F3, `window[64]` proof). +4. The bad state starts at one launch and persists module-wide for the boot; the m155 lane-tail rearm + re-enqueues + reloads the context but does not revive dispatch (F4). +5. `CWD_T0=0x12480` is not a discriminator (good ok=1/2/3/5/6 share it). +6. m154 ring-pin drop is live (1 drop in r155) and covers its class. +7. Host-side launch state (win0 param, guest param, fills) verified identical pre/post by the m151 + hashes on the failing launch. + +**Hypothesis (needs E1/E2/E3/E6):** +1. 2-bank win0 / single-buffered qmdwin reuse-while-in-flight is the no-execute trigger (F5.1/2). +2. Engine-side stale const/PTE read is the stale/mixed-tuple class; the fix is more bank depth or the + ctx-window/chunked data path (AGENT-C R3/R4). +3. Warm sem push revives dispatch (E5). +4. A register signature exists that separates wedged from executed-idempotent (E6). + +**Recommended first action for the next live session:** E1 + E7 (both no-code/one-flag) on a fresh +cycle, then land E2 (4-bank) as the first code change — it is the only change whose mechanism is +supported by this boot's transition timing and cannot regress a working launch. |
