summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArthur Hanson Rasmusson <arthur@vgpu.io>2026-11-02 02:34:49 -0500
committerArthur Hanson Rasmusson <arthur@vgpu.io>2026-11-02 02:34:49 -0500
commit0eb6411800011a0614fba95c416fae00ec9e0efd (patch)
treec3fcd43883ae6365977eae04aab50ac460827bf6
parent07bc59da291be0da1e4416d89310716b62696b9f (diff)
downloadopen-iov-0eb6411800011a0614fba95c416fae00ec9e0efd.tar.gz
open-iov-0eb6411800011a0614fba95c416fae00ec9e0efd.zip
vgsp: CONT-109 - FOUR FIXES: (1) WEDGE-RECOVER now rewinds pack_off/pack_sa + invalidates live_gen (r1377 deadlock: recovery reset pre_emit_off=0 but left pack_off at end -> split emitter can=0->packed=1 zero words -> MME-PRELUDE part gen=3 off=0 words=0/3083 forever, latch never re-set, MME never started); (2) PARK-RECOVER same rewinds; (3) gsp_phys_gr_fetch_miss_log promotes live_gen on GP_GET advance (readback-free promotion on timeout path; r1377 lost it FETCH-WIT timeout engine-fetched then pending_gen cleared); (4) gsp_phys_mme_fast_sample latches poisoned when sample's FIRST read is poison (r1378 MME-FAST begin esr=badf1201 ds=badf1201 grfifo=badf1201 -> esr badf1201->80000000 was missed; stale latch+live then ran macro 57 on wiped context sked mme_esr=80000004 mme_mac=0x39, FE parked pc=513 mac=0xf1 mmegen=1) - PROGRESS (not gate claim): r1378 MME-FAST launch macro-status=000393a2(mpc=930 mac=0x39 run=0) MACRO 57 EXECUTED TO ITS LAST INSTRUCTION; STORES GREW 9/909 -> 238/906 -> 305/903 (r1378); r1379 clean boot (0x mme_esr=80000004, no WEDGE-RECOVER) float-vertex stores 4/906 50/970; guest 5447 frames in 12.1s = 448.994 FPS (fence-level only not pixels); GATE1 BLACK both boots: r1378/r1379 xwd 1280x720 nonblack 0 max 0; r1379 staging page-note va=0x4500000 pa=0x1035f1000 has 2517 nonzero bytes but content is a DESCRIPTOR TABLE (28cd1000 00000001 68cd1000 ffff8a74) not pixels; every retire 0/903 - A/B bisect inconclusive (flipped live but no new beef launches, client moved to software release; needs insmod arming) - next: arm wedge bisect at insmod on fresh boot (sema_gl_mme_keep_mask=0 sema_gl_mme_nop_drop=0xffffffffffffffff before client launches): clean => executed macros' emitted methods (0x2390/0x34a4 CB writes) park FE; still poisons => win_drop non-call families (SURF-PRELUDE/SHADER-EXC 0x1528/SPH-REGION/SA-REARM); then output retirement must move off 0/N before sema_screen_blit (src=drawable GPA dst_off=0x200000 pitch 5120) can present - SESSION 153 r1378-r1379
-rw-r--r--kernel/gsp_phys_booter.c79
1 files changed, 77 insertions, 2 deletions
diff --git a/kernel/gsp_phys_booter.c b/kernel/gsp_phys_booter.c
index 55c2170..43ab00f 100644
--- a/kernel/gsp_phys_booter.c
+++ b/kernel/gsp_phys_booter.c
@@ -5358,6 +5358,28 @@ static bool gsp_phys_mme_fast_sample(void __iomem *bar0, const char *tag,
gf_p = ioread32(bar0 + 0x00400504u);
tr_p = ioread32(bar0 + 0x00400704u);
/*
+ * SESSION 153-CONTINUED-109: the poison episode can already be
+ * latched when the sample's FIRST read happens. r1378's first
+ * window+live launch: `MME-FAST begin launch ... esr=badf1201
+ * ds=badf1201 grfifo=badf1201 trap=badf1201` with the very next
+ * read clean (`esr badf1201->80000000 ... grfifo badf1201->
+ * 00000001`). The historical detector only marks `poisoned` when a
+ * POST-entry read shows poison, so the episode was never handed to
+ * the WEDGE-RECOVER decision - no recovery ran, the prelude latch
+ * and live_gen stayed set, and every later calls-bearing window
+ * executed macro 57 against the wiped MME context: sked
+ * `mme_esr=80000004 (ILLEGAL_OPCODE) mme_mac=0x39`, then the FE
+ * parked at pc=513/mac=0xf1 and the stores stopped (0/905 after the
+ * 305-page burst). Treat an entry read of poison as the same
+ * witness; the FECS has already reset the context, so the recovery
+ * (latch clear + cursor rewind + live_gen invalidate) is exactly
+ * what is owed.
+ */
+ if (((gf_p & 0xffff0000u) == 0xbadf0000u) ||
+ ((esr_p & 0xffff0000u) == 0xbadf0000u) ||
+ ((ds_p & 0xffff0000u) == 0xbadf0000u))
+ poisoned = true;
+ /*
* SESSION 153-CONTINUED-84: FE_DECODE_STATE_EX(0)/(1) also drive a
* transition log - the MME's macro/generated witness can flip
* there without touching ESR/DS/grfifo, which is exactly the
@@ -22717,8 +22739,32 @@ gsp_phys_gr_fetch_miss_log(u32 h_object,
pr_info("vgsp-gr: FETCH-WIT %s h=0x%x slot=%u gpget %u->%u %s\n",
tag, h_object, sub->slot, sub->gpget, usr_gpget,
usr_gpget != sub->gpget ? "engine-fetched" :
- "GP_GET-frozen (NOT fetched: parked or over-cap block)");
- WRITE_ONCE(gsp_phys_gr_mme_pending_gen, 0);
+ "GP_GET-frozen (NOT fetched: parked or over-cap block)");
+ /*
+ * SESSION 153-CONTINUED-109: readback-free live promotion on the
+ * timeout path. The poll-break path promotes the generation whose
+ * final prelude part was carried when GP_GET advanced (the engine
+ * consumed the entry). A launch can also time out the w0/w1 release
+ * wait AFTER the engine fetched it (r1377: `FETCH-WIT timeout ...
+ * gpget 5->6 engine-fetched` on the load-only carriers - their
+ * releases only matched ~10 s later through the ladder), and the
+ * historical code cleared pending_gen here, permanently losing the
+ * promotion: live_gen never caught pl_gen, every later launch stayed
+ * window-elided, and the MME never got a calls-bearing launch
+ * (`pc_valid=0` on all samples). Promote on the same GP_GET witness
+ * the break path trusts; only a genuinely unfetched carrier clears.
+ */
+ if (usr_gpget != sub->gpget &&
+ READ_ONCE(gsp_phys_gr_mme_pending_gen)) {
+ pr_info("vgsp-gr: MME-LIVE promote via GP_GET advance (%s) gen=%u h=0x%x\n",
+ tag, READ_ONCE(gsp_phys_gr_mme_pending_gen),
+ h_object);
+ WRITE_ONCE(gsp_phys_gr_mme_live_gen,
+ READ_ONCE(gsp_phys_gr_mme_pending_gen));
+ WRITE_ONCE(gsp_phys_gr_mme_pending_gen, 0);
+ } else {
+ WRITE_ONCE(gsp_phys_gr_mme_pending_gen, 0);
+ }
}
/*
@@ -27913,6 +27959,32 @@ gr_page_unmapped:
* the owed re-preload.
*/
WRITE_ONCE(gsp_phys_gr_mme_pre_emit_off, 0);
+ /*
+ * SESSION 153-CONTINUED-109: rewind the PACK
+ * cursor too (the r1377 deadlock: recovery reset
+ * pre_emit_off but left pack_off at its end, so
+ * the split emitter hit `poff >= maxa` -> can=0
+ * -> packed=1 with zero words on every launch:
+ * `MME-PRELUDE part gen=3 off=0 words=0/3083`
+ * forever, latch never re-set, gates never
+ * release, MME never starts). The gate-fail
+ * path (gsp_phys_gr_mme_iram_gate_fail) already
+ * rewinds both cursor pairs.
+ */
+ WRITE_ONCE(gsp_phys_gr_mme_pack_off, 0);
+ WRITE_ONCE(gsp_phys_gr_mme_pack_sa, false);
+ /*
+ * SESSION 153-CONTINUED-109: the hard re-arm
+ * wiped the engine context, so the generation
+ * whose carrier executed is no longer resident.
+ * Invalidate it; the re-preload's own GP_GET
+ * advance (readback-free witness) re-promotes
+ * (fetch_miss/poll-break paths). Without this
+ * the stale live_gen would mark a wiped context
+ * live and the next window+calls launch would
+ * run against an unloaded MME.
+ */
+ WRITE_ONCE(gsp_phys_gr_mme_live_gen, 0);
pr_warn("vgsp-gr: WEDGE-RECOVER after re-arm grfifo=0x%08x (%s); recovery #%u this boot; MME prelude latch cleared (context re-preload owed)\n",
g1,
(g1 & 0xffff0000u) == 0xbadf0000u ?
@@ -28242,6 +28314,9 @@ gr_page_unmapped:
if (!sp_ret) {
WRITE_ONCE(gsp_phys_gr_mme_prelude_gen, 0);
WRITE_ONCE(gsp_phys_gr_mme_pre_emit_off, 0);
+ WRITE_ONCE(gsp_phys_gr_mme_pack_off, 0);
+ WRITE_ONCE(gsp_phys_gr_mme_pack_sa, false);
+ WRITE_ONCE(gsp_phys_gr_mme_live_gen, 0);
pr_warn("vgsp-gr: PARK-RECOVER #%u warm sem ALIVE after TSG preempt + resched; fresh-entry retries resume push=0x%llx\n",
park_rec_n, req->push_va);
} else {