summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--kernel/gsp_sema_service.c125
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;