FABRIC.md: item 4.5d -- arch_relax() tested against the PM Timer stall, disproven

Follow-up probing narrowed Finding 3's behavior (inconsistent stall point
run-to-run: sometimes reaches iters=1000/delta=951 before stopping,
sometimes never gets past iters=0 even after a 400-second bounded wait) but
didn't pin the mechanism.

Tested the strongest available hypothesis: single-threaded TCG scheduling
starvation from an -O2-tightened spin loop, based on a real precedent --
calibrate_apic_timer() (apic.c) already calls arch_relax() every iteration
of its own spin-wait; calibrate_tsc_with_pmtimer() never had it. Added the
same call, matching that precedent exactly. Result: no change, same exact
stall point on a fresh 60-second bounded wait. Reverted.

Stopping here per this document's own §25.0 rule 5 -- root-causing further
needs either deeper TCG/QEMU internals knowledge or a different diagnostic
approach (host-side instrumentation) than another guess-and-check pass.
Makefile.starkernel and timer.c both back to committed -O0 state, confirmed
booting clean.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Robert Allan James
2026-08-11 11:35:09 -04:00
co-authored by Claude Sonnet 5
parent 7df2e1bae3
commit dd09de65f5
10 changed files with 18655 additions and 37 deletions
+36
View File
@@ -5598,6 +5598,42 @@ document and committing that amendment as its own item.*
> more expensive under `-O2`, mechanism unknown) or a genuine non-terminating condition;
> the evidence gathered doesn't yet distinguish the two. Probe reverted after capture, not
> left in the tree. `Makefile.starkernel` reverted to `-O0` again; nothing broken landed.
>
> **Follow-up probing, 2026-08-11.** A second, finer-grained one-shot probe (checkpoint
> every 1000 iterations instead of `0x100000`) caught one full run: `iters=0 delta=67`, then
> `iters=1000 delta=951` (~462 TSC cycles/iteration, unremarkable) — genuinely close to the
> `target_ticks=1000` exit condition — then nothing for the rest of a 40s window; the loop
> never reached `iters=2000`. A third run with per-iteration granularity around the
> 9001100 range caught **only** `iters=0` before a **400-second (6.7 minute)** bounded wait
> expired — worse than the first two runs, and inconsistent run-to-run in exactly how far it
> gets, which itself is informative: this isn't a fixed, deterministic slowdown factor.
>
> **Hypothesis tested and disproven:** single-threaded TCG's cooperative scheduling being
> starved by an -O2-tightened loop body — meaning the emulated PM Timer's own host-side
> update never gets a chance to run, so `cur` stops advancing from the guest's perspective —
> seemed well-supported by a concrete precedent: `calibrate_apic_timer()` in `apic.c:382-406`
> (a sibling calibration loop, same file family, same TCG target) already calls
> `arch_relax()` (x86 `PAUSE`, `include/starkernel/arch.h:76`, "architecture-friendly
> pause/yield hint inside busy loops") on every iteration of its own spin-wait, while
> `calibrate_tsc_with_pmtimer()` never had it. Added `#include "arch.h"` and one
> `arch_relax();` call per loop iteration, matching that precedent exactly. **Result: no
> change.** Same exact stall point (`Timer: CPUID frequency unavailable; trying PM
> Timer...`, then nothing), confirmed with a fresh 60-second bounded wait. Reverted (both
> the `#include` and the `arch_relax()` call, plus `Makefile.starkernel` back to `-O0`);
> amd64 boots clean again at `-O0`, confirmed.
>
> **Where this leaves it:** the starvation hypothesis isn't confirmed wrong, exactly — `x86
> PAUSE` is documented to matter most for VM-exit-based virtualization (KVM), and this
> project's entire acceptance methodology is TCG-only (software emulation, no VM-exits to
> hand control to a scheduler); `PAUSE` alone may simply not be the right primitive for
> whatever TCG-specific mechanism is actually at play here, if that theory holds at all. No
> alternative hypothesis has been tested. This is squarely a "stop and report" point per
> this document's own §25.0 rule 5 — root-causing further needs either deeper TCG/QEMU
> knowledge than has been brought to bear so far, or a fundamentally different diagnostic
> approach (e.g., instrumenting on the QEMU/host side rather than guest-side probes) that's
> a bigger step than another guess-and-check pass. Notable stakes: per CLAUDE.md, QEMU/TCG
> is not *a* target for this project, it's *the* acceptance target — this bug blocks the
> actual thing that matters, not an edge case.
> 4.5d cannot complete until this is resolved.
- [ ] **4.5e — Three-arch acceptance boot with optimization enabled.** Depends on 4.5d. This