diff options
| -rw-r--r-- | kernel/gsp_sema_service.c | 125 |
1 files changed, 116 insertions, 9 deletions
diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c index d856241..8f194e9 100644 --- a/kernel/gsp_sema_service.c +++ b/kernel/gsp_sema_service.c @@ -1975,6 +1975,14 @@ static u32 svc_ring_pin_skips; * content-validated (entry0 must parse; a discovered base must carry this * channel's slot), so re-arming is safe and idempotent within a session. */ +/* + * SESSION 153-CONTINUED-76: the GR stale-ring heal timestamps live here so + * the channel-add path can force an immediate heal for a re-registered + * channel (see gsp_sema_service_channel_add). Declared before its use in + * the add path; the heal itself is defined with the ring-heal section. + */ +static unsigned long svc_gr_heal_at[32]; + static void svc_chan_rearm_rank(struct svc_channel *ch) { if (!ch || !ch->valid) @@ -2239,6 +2247,18 @@ void gsp_sema_service_channel_add(const struct sema_channel_desc *desc) * the previous session's one-shot state (second-client wedge). */ svc_chan_rearm_rank(ch); + /* + * SESSION 153-CONTINUED-76: a re-registered GR channel starts + * the stale-ring heal immediately instead of waiting out the + * previous instance's 1 s gate. The client churns its channels + * every ~12 s; a ring pin inherited from the dead session (the + * session flush may have been raced by this registration, see + * the add-vs-flush skip) can keep answering with the previous + * ring's pages for the new instance, and the ~40 passes the + * USERD/FB sweeps need must not also wait on the heal. + */ + if (!ch->engine_type && ch->gr_index < 32) + svc_gr_heal_at[ch->gr_index] = 0; svc.last_chan_reg = jiffies; /* * CeUtils scrubber channel: NUM_COPY_BLOCKS = 4096 GPFIFO @@ -21152,6 +21172,21 @@ static int svc_chan_userd(struct nv_vgpu_device *vgpu, struct svc_channel *ch, } /* + * SESSION 153-CONTINUED-76: name the gated-out case too. The churning + * GL client's failing instance showed neither a sweep line nor an + * adoption; if the ring parameter never resolves post-re-registration + * the whole r496b sweep is skipped and the failure is invisible. + */ + if (gsp_sema_dbg && !ch->engine_type && !ring_pa && !ch->userd_ok && + (ch->fb_userd_scan_n == 0u || ch->fb_userd_scan_n == 64u) && + (ch->h_object >= 0xbeef0000u && ch->h_object <= 0xbeefffffu)) { + ch->fb_userd_scan_n++; + pr_info("sema-chan: userdp no-sweep h=0x%x ring_pa=0 n=%u gr_ram_ring=%d (r496b gated on an unresolved ring)\n", + ch->h_object, ch->fb_userd_scan_n, + ch->gr_ram_ring ? 1 : 0); + } + + /* * r496b: no candidate matched. For a GR channel whose ring is known * (translated and pinned - the sysmem content scan or the VRAM * conventions), the USERD may still be elsewhere: the X/GL driver @@ -21189,6 +21224,21 @@ static int svc_chan_userd(struct nv_vgpu_device *vgpu, struct svc_channel *ch, u32 best_put = 0, best_get = 0; bool best_pending = false; u32 gate_n = 0, vfail_n = 0; + /* + * SESSION 153-CONTINUED-76: post-re-registration ring reads. + * The client churns its channels every ~12 s and a ring pin + * inherited from the dead instance can shadow the walk in + * svc_lookup; validated FELL through the stale pin made every + * candidate fail and the re-registered channel never got its + * USERD (top-level contention.75). Resolve the ring page + * through the client's OWN VAS walk once per sweep and retry + * each failed entry read there: the walk is the authority for + * the live session, the pin only a cache. + */ + u64 wp = 0; + int wap = SVC_APERTURE_SYS; + bool wtry = false, wused = false; + u32 woff = (u32)(ch->gpfifo_va & (SEMA_PAGE_SIZE - 1)); ch->fb_userd_scan_at = jiffies; ch->fb_userd_scan_n++; @@ -21227,6 +21277,34 @@ static int svc_chan_userd(struct nv_vgpu_device *vgpu, struct svc_channel *ch, (u64)k * 8, e, sizeof(e)); if (rdrc) { + /* + * CONT-76 walk fallback: a stale + * or missing pin must not veto a + * candidate the live session's own + * page tables can answer. Resolve + * the ring page once per sweep and + * re-read the entry from it. + */ + if (!wtry && !wp) { + wtry = true; + if (svc_walk_vaspaces(vgpu, + ch->gpfifo_va & + ~(u64)(SEMA_PAGE_SIZE - 1), + &wp, &wap)) + wp = 0; + } + if (wp && + (u64)woff + (u64)k * 8 + 8 <= + SEMA_PAGE_SIZE) { + rdrc = svc_read_ap(vgpu, + wp + woff + + (u64)k * 8, + wap, e, sizeof(e)); + if (!rdrc) + wused = true; + } + } + if (rdrc) { ok = false; rck = (int)k; /* -1: read failure rc; else the @@ -21335,12 +21413,28 @@ static int svc_chan_userd(struct nv_vgpu_device *vgpu, struct svc_channel *ch, * r820 diag: the sweep found nothing adoptable. gates * counts put/get-coherent blocks seen, vfails the ones * rejected by the ring-entry validation. + * + * SESSION 153-CONTINUED-76: the global r820 budget + * (svc_userdp_log < 512) was spent by other channels + * before the churning GL client's ranks ever swept, so + * its post-re-registration failure was invisible. Log + * the sweep result for GR ranks at fixed per-instance + * scan numbers (3 lines per instance max) regardless of + * the global budget, with the walk answer included so + * the stale-pin vs dead-walk distinction is in the + * record. */ - if (gsp_sema_dbg && svc_userdp_log < 512) { + if (gsp_sema_dbg && + (svc_userdp_log < 512 || + (!ch->engine_type && + (ch->fb_userd_scan_n == 4u || + ch->fb_userd_scan_n == 64u || + ch->fb_userd_scan_n == 256u)))) { svc_userdp_log++; - pr_info("sema-chan: userdp sweep h=0x%x scans=%u gates=%u vfails=%u best=0x%llx\n", + pr_info("sema-chan: userdp sweep h=0x%x scans=%u gates=%u vfails=%u best=0x%llx ring_pa=0x%llx walk=0x%llx used=%d\n", ch->h_object, ch->userd_scans, - gate_n, vfail_n, best); + gate_n, vfail_n, best, ring_pa, wp, + wused ? 1 : 0); } } } @@ -23207,15 +23301,29 @@ static void svc_gr_setup_hold_arm(struct svc_channel *ch, u64 va, u32 idx, u64 page = va & ~(u64)(SEMA_PAGE_SIZE - 1); u32 poff; - if (!va || !gsp_sema_gr_setup_hold_ms) + if (!va) return; + /* + * SESSION 153-CONTINUED-76: the page demand is DECOUPLED from the + * hold. The r1157 live A/B proved the 20 s hold derails the client + * (the ring stalls behind the unreadable setup entry and the client's + * ~10 s fence timeout churns the channel), while with the demand also + * disabled (early return) the unreadable setup push's pages are never + * demanded, never pinned, and the 0x114/0x11c/0x120 macro-program + * runs stay zeros. Keep emitting the demand rows for the entry with + * the hold off; one emission per (va,slot). + */ if (ch->gr_setup_hold_va != va || ch->gr_setup_hold_idx != idx) { ch->gr_setup_hold_va = va; ch->gr_setup_hold_idx = idx; - ch->gr_setup_hold_until = - jiffies + msecs_to_jiffies(gsp_sema_gr_setup_hold_ms); - pr_info("sema-chan: GR setup hold h=0x%x entry=%u va=0x%llx len=%u armed (demanding 4K pages; pending until the pin lands, window %u ms)\n", - ch->h_object, idx, va, len, gsp_sema_gr_setup_hold_ms); + if (gsp_sema_gr_setup_hold_ms) + ch->gr_setup_hold_until = jiffies + + msecs_to_jiffies(gsp_sema_gr_setup_hold_ms); + else + ch->gr_setup_hold_until = 0; + pr_info("sema-chan: GR setup hold h=0x%x entry=%u va=0x%llx len=%u armed (demanding 4K pages; hold=%u ms; pending until the pin lands)\n", + ch->h_object, idx, va, len, + gsp_sema_gr_setup_hold_ms); } for (poff = 0; poff < len && poff < 0x40000u; poff += SEMA_PAGE_SIZE) { svc_log_stalled_va(page + poff); @@ -23504,7 +23612,6 @@ static void svc_kick_ring_revalidate(struct nv_vgpu_device *vgpu, * fails the gate, nothing is touched: the heal can only replace a * provably-dead translation with a provably-plausible one. */ -static unsigned long svc_gr_heal_at[32]; static u32 svc_gr_heal_log; static u64 svc_gr_heal_n; |
