From 0eb6411800011a0614fba95c416fae00ec9e0efd Mon Sep 17 00:00:00 2001 From: Arthur Hanson Rasmusson Date: Mon, 2 Nov 2026 02:34:49 -0500 Subject: 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 --- kernel/gsp_phys_booter.c | 79 ++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 77 insertions(+), 2 deletions(-) (limited to 'kernel') 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 @@ -5357,6 +5357,28 @@ static bool gsp_phys_mme_fast_sample(void __iomem *bar0, const char *tag, ds_p = ioread32(bar0 + 0x00405840u); 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 @@ -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 { -- cgit v1.2.3