From 770d6b4af7f44acc104c6149b9c473de1db607e7 Mon Sep 17 00:00:00 2001 From: Arthur Hanson Rasmusson Date: Thu, 12 Nov 2026 23:25:00 -0500 Subject: vgsp: flip-event delivery defaults to assoc+strict (clears Flip event timeout); DDX latch reset clauses Wall (b) 'Flip event timeout on head 0' fix (validated c171): NVKMS/kernel- callback events register hSrcResource=0, so every display UPDATE completion rode the all-events shotgun (6-7 POST_EVENT records each), the guest's status-queue read cursor fell 20-44 slots behind (rc=-11 ring-full bursts) and flip records arrived past the 3 s NvDrm window. Default the r1765 pair ON - gsp_rm_ev_assoc (hSrc==0 -> alloc-parent channel) and gsp_disp_events_strict (armed UPDATE posts only to that channel's events, no fallback) - the exact combination r1771 measured as '0 flip WARNs'. Validating cycle c171: registrations carry real sources (hEvent=0x1007a hSrc=0x1001b etc.), UPDATE posts are exact 1:1 (posts=27), WARN count 1 for the boot, serial timeouts=0 (c160 pre-fix: 34). Both stay runtime-writable. Also stage the gsp_sema_service.c candidates for wall (a) (the later-DMA 0x51 is a consequence of 'Failed to idle DMA' on a recycled channel): the served-refusal in svc_userd_ddx_reprobe now exempts a latch reset to put==0, and the put-reset latch keep extends to the DDX family (was kick-only). These clauses target c171's observed reset/junk-adopt sequence; validation pending on a roll where wall (a) is otherwise survivable. --- kernel/gsp_sema_service.c | 36 ++++++++++++++++++++++++++++++++---- 1 file changed, 32 insertions(+), 4 deletions(-) (limited to 'kernel/gsp_sema_service.c') diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c index ced815d..6f4e387 100644 --- a/kernel/gsp_sema_service.c +++ b/kernel/gsp_sema_service.c @@ -43992,8 +43992,18 @@ static bool svc_userd_ddx_reprobe(struct nv_vgpu_device *vgpu, * validated block inside the client's ~10 s DMA-test window. The * pump's confirm/reject/defer ladder still owns the latch's lifetime * (defer bound 32, then reject -> the RAM scan re-adopts fresh). - */ - if (ch->submissions != ch->gr_ram_userd_latch_sub) + * + * r1780 (eng5 c171): EXCEPT when the served latch has been RESET to + * put==0 - the client recycled the control block (the DDX's next + * push-on-demand generation). A block at put==0 is not "serving" + * anything, so the switch to a freshly validated live block must be + * allowed; without this the served-refusal kept the zeroed block and + * the channel stayed dark (c171: "Failed to idle DMA" t=88.3). The + * keep path in the pump's judge re-arms latch_put to 0 on the reset, + * so this exception only fires for recycled blocks. + */ + if (ch->submissions != ch->gr_ram_userd_latch_sub && + ch->gr_ram_userd_latch_put != 0) return false; if (!svc_gr_ram_userd_scan(vgpu, ch, &npa, &nput, &nget)) return false; @@ -44952,8 +44962,9 @@ static void svc_pump_channels(struct nv_vgpu_device *vgpu) pr_info("sema-chan: GR USERD h=0x%x pa=0x%llx speculative latch CONFIRMED (put %u -> %u)\n", ch->h_object, ch->userd_pa, ch->gr_ram_userd_latch_put, put); - } else if (kfam && (gsp_sema_kick_latch_keep || - ch->gr_ram_userd_confirmed) && + } else if ((kfam || svc_userd_ddx_family(ch)) && + (gsp_sema_kick_latch_keep || + ch->gr_ram_userd_confirmed) && put == 0 && ch->gr_ram_userd_latch_put != 0 && ch->gr_ram_userd_keeps < 64) { @@ -44975,6 +44986,23 @@ static void svc_pump_channels(struct nv_vgpu_device *vgpu) * after; the ADOPT itself was ring-entry- * validated). sema_kick_latch_keep=0 restores * the pre-fix condition for A/B. + * + * r1780 (eng5 c171, later-DMA instance): the + * same put-reset applies to the DDX family's + * served latch. The X channel 0x1000013 had + * served 7698 slots, the DDX's next push-on- + * demand generation recycled the control block + * (put 7698 -> 0), and because the reset sets + * `moved` the DEFERRED clause below did not + * apply -> REJECT -> the FB shape scan adopted + * a garbage block ("found by VRAM shape scan + * at fb 0x960000 (put=1 get=917535, idle, + * ring-validated)", reads 0/0) -> "Failed to + * idle DMA" at Xorg t=88.3. Keep the reset + * block re-armed; the 2 s re-probe (with the + * zeroed-latch exception in + * svc_userd_ddx_reprobe) finds the real new + * generation. */ ch->gr_ram_userd_keeps++; if (ch->gr_ram_userd_keep_log < 8) { -- cgit v1.2.3