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:
co-authored by
Claude Sonnet 5
parent
7df2e1bae3
commit
dd09de65f5
@@ -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
|
||||
> 900–1100 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
|
||||
|
||||
Reference in New Issue
Block a user