summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArthur Hanson Rasmusson <arthur@vgpu.io>2026-11-13 01:35:20 -0500
committerArthur Hanson Rasmusson <arthur@vgpu.io>2026-11-13 01:35:20 -0500
commit296906351bc671e60a3dfbbad8eae3e667227195 (patch)
treee5f4a003768f24e673ac2572ff1c058fce968c60
parentb9213c57222026eacc41dbcec079190c27f7e111 (diff)
downloadopen-iov-296906351bc671e60a3dfbbad8eae3e667227195.tar.gz
open-iov-296906351bc671e60a3dfbbad8eae3e667227195.zip
vgsp: DDX latch adoption grace + last-proven-block parking (X now lives >10 min)
Thread A of the X longevity wall, validated c195/c198 (rich args + tick): - Adoption grace: gr_ram_userd_adopt_at stamped at every DDX fresh-adopt site; svc_userd_ddx_reprobe refuses a speculative switch within 1 s of an adopt (kills the c190/c197 same-pass cascade to frozen lookalikes). - Clause 3: the last CONFIRMED block is parked (pa/as/put/probes) on every DDX confirm; svc_userd_ddx_park_probe checks it first in the re-probe and discovery scan and prefers it when its PUT advances across two probes (kick excluded, half-ring bound, reset re-syncs). Receipts: c195 X GREEN >10 min with 0 DMA failures ('shape scan fb 0x8f0000 -> CONFIRMED 2->6 at +63 ms, zero SWITCHED/DEFERRED/REJECTED all boot'); c198 GREEN >2 min likewise (+69 ms confirm, zero switches). Residual (documented): the RAM-scan 'LIVE' vote can still admit pool lookalikes on a first generation before any block is parked; the grace only delays that switch. Thread B (documented, no change): in c195's green window gl_frames still reads black (px0=0, ~12 s/frame) although the rich args capture the modern-GL sections ('sema-gl: 3D stream marked', 'section captured len=1524' + 2 draw sections, prog-images vs=1408 ps=384) - ZERO GR LAUNCH and zero readback/copy-out lines; the beef0100 channel re-registers every ~13 s with submissions=0. Modern-GL work is section-captured but never executed/forwarded - the next frontier.
-rw-r--r--kernel/gsp_sema_service.c209
1 files changed, 177 insertions, 32 deletions
diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c
index 9e0f3f4..34e2b49 100644
--- a/kernel/gsp_sema_service.c
+++ b/kernel/gsp_sema_service.c
@@ -783,6 +783,23 @@ struct svc_channel {
unsigned long gr_ram_userd_reject_at; /* jiffies of last reject */
unsigned long gr_ram_userd_reprobe_at; /* last live-latch re-probe */
/*
+ * r1780 (eng8 X-longevity): latch-integrity state. adopt_at stamps a
+ * FRESH latch adopt (RAM scan, FB shape scan or a re-probe switch).
+ * The DDX re-probe refuses any speculative switch within a 1 s grace
+ * of a fresh adopt (c190 adopted 0x11ab58000 at T and switched to
+ * the frozen 0x12e143000 27 ms later in the same pass; grace keeps
+ * the fresh adopt's own 10 s DMA window intact). park_* remembers the
+ * last CONFIRMED DDX block (pa+aperture+PUT): the client's next
+ * push-on-demand generation often re-allocates near or on the proven
+ * block, so the re-probe/scan checks the parked block FIRST and
+ * prefers it once its PUT advances across two probes.
+ */
+ unsigned long gr_ram_userd_adopt_at; /* jiffies of the fresh adopt */
+ u64 gr_ram_userd_park_pa; /* last CONFIRMED DDX userd_pa */
+ int gr_ram_userd_park_as; /* its aperture */
+ u32 gr_ram_userd_park_put; /* parked PUT at the last probe */
+ u8 gr_ram_userd_park_probes; /* consecutive advancing probes */
+ /*
* SESSION 154 (M-GL1.2): content anchor for a client push whose
* translation went stale (r913: a validated pin kept answering for
* a reused page and the wrong-VAS walk answer was implausible while
@@ -5242,6 +5259,9 @@ static void svc_pin_drop(u64 va)
static inline bool svc_pool_sem_va(u64 va);
static bool svc_kick_family(const struct svc_channel *ch);
static bool svc_userd_ddx_family(const struct svc_channel *ch);
+static bool svc_userd_ddx_park_probe(struct nv_vgpu_device *vgpu,
+ struct svc_channel *ch, u64 *pa_out,
+ u32 *put_out, u32 *get_out);
static void svc_pool_pa_forget(u64 va);
/*
@@ -27408,10 +27428,19 @@ static int svc_chan_userd(struct nv_vgpu_device *vgpu, struct svc_channel *ch,
(svc_userd_ddx_family(ch) && ch->gr_ram_userd_rejects < 255))) {
u64 upa = 0;
u32 uput = 0, uget = 0;
+ /*
+ * r1780 (eng8 clause ii): the parked proven block goes FIRST
+ * on this scan too (the channel may have lost its latch and
+ * the proven layout is the likeliest re-allocation target).
+ */
+ bool parked = svc_userd_ddx_park_probe(vgpu, ch, &upa, &uput,
+ &uget);
- if (svc_gr_ram_userd_scan(vgpu, ch, &upa, &uput, &uget)) {
+ if (parked ||
+ svc_gr_ram_userd_scan(vgpu, ch, &upa, &uput, &uget)) {
ch->userd_pa = upa;
- ch->userd_as = SVC_APERTURE_SYS;
+ ch->userd_as = parked ? ch->gr_ram_userd_park_as :
+ SVC_APERTURE_SYS;
ch->userd_ok = true;
/* r1653: decode the skipped first entries for the
* class2d kick arm before the walk seed below. */
@@ -27442,13 +27471,16 @@ static int svc_chan_userd(struct nv_vgpu_device *vgpu, struct svc_channel *ch,
ch->gr_ram_put_seeded = uput;
ch->gr_ram_userd_latch_put = uput;
ch->gr_ram_userd_latch_at = jiffies;
+ ch->gr_ram_userd_adopt_at = jiffies;
ch->gr_ram_userd_latch_sub = ch->submissions;
ch->gr_ram_userd_defers = 0;
ch->gr_ram_userd_confirmed = false;
*put = uput;
*get = uget;
- pr_info("sema-chan: GR USERD h=0x%x rank=%u found by RAM scan -> pa=0x%llx (put=%u get=%u%s; entries ring-validated; speculative, pump confirms; walk seed last_get=%u)\n",
- ch->h_object, ch->gr_index, upa, uput, uget,
+ pr_info("sema-chan: GR USERD h=0x%x rank=%u found by %s -> pa=0x%llx (put=%u get=%u%s; entries ring-validated; speculative, pump confirms; walk seed last_get=%u)\n",
+ ch->h_object, ch->gr_index,
+ parked ? "parked proven block" : "RAM scan",
+ upa, uput, uget,
uget < uput ? "" : ", idle",
(u32)ch->last_get);
return 0;
@@ -27840,6 +27872,7 @@ ce_fb_scan:
*/
ch->gr_ram_userd_latch_put = best_put;
ch->gr_ram_userd_latch_at = jiffies;
+ ch->gr_ram_userd_adopt_at = jiffies;
ch->gr_ram_userd_latch_sub = ch->submissions;
ch->gr_ram_userd_defers = 0;
ch->gr_ram_userd_confirmed = false;
@@ -44005,6 +44038,66 @@ static bool svc_userd_put_wrap(const struct svc_channel *ch)
}
/*
+ * r1780 (eng8 X-longevity clause i): no speculative re-probe switch within
+ * this window of a fresh latch adopt. c190 adopted the RAM-scan LIVE block
+ * 0x11ab58000 and the same pass's re-probe switched to the frozen
+ * 0x12e143000 27 ms later; the fresh adopt never got to prove itself
+ * (DEFERRED hold -> "Failed to idle DMA").
+ */
+#define SVC_USERD_DDX_ADOPT_GRACE_MS 1000
+
+/*
+ * r1780 (eng8 X-longevity clause ii): parked proven-block preference. The
+ * park fields hold the last CONFIRMED DDX latch block. Probe it on every
+ * re-probe/scan call: read its PUT, and once it advances (a bounded
+ * forward step, same half-ring bound as the CONFIRM judge) across TWO
+ * consecutive probes, return it as the preferred candidate - client-
+ * authored liveness on the proven layout beats any fresh scan candidate.
+ * A reset re-syncs the baseline without counting; an unreadable or
+ * nonsense page drops the park. Kick-family blocks are excluded (their
+ * PUT is free-running and the kick watch owns their adoption).
+ */
+static bool svc_userd_ddx_park_probe(struct nv_vgpu_device *vgpu,
+ struct svc_channel *ch, u64 *pa_out,
+ u32 *put_out, u32 *get_out)
+{
+ u32 pput = 0, pget = 0, step;
+
+ if (!ch->gr_ram_userd_park_pa || !ch->gr_ram_userd_park_as)
+ return false;
+ if (svc_kick_family(ch))
+ return false;
+ if (ch->userd_ok && ch->gr_ram_userd_park_pa == ch->userd_pa)
+ return false; /* the proven block is already the latch */
+ if (svc_read_ap(vgpu, ch->gr_ram_userd_park_pa + SVC_USERD_GP_PUT,
+ ch->gr_ram_userd_park_as, &pput, sizeof(pput)) ||
+ !pput || pput > 0x100000) {
+ ch->gr_ram_userd_park_pa = 0;
+ ch->gr_ram_userd_park_as = 0;
+ ch->gr_ram_userd_park_put = 0;
+ ch->gr_ram_userd_park_probes = 0;
+ return false;
+ }
+ step = pput > ch->gr_ram_userd_park_put ?
+ pput - ch->gr_ram_userd_park_put : 0;
+ if (step && ch->gpfifo_entries >= 2 &&
+ step <= ch->gpfifo_entries / 2)
+ ch->gr_ram_userd_park_probes++;
+ else
+ ch->gr_ram_userd_park_probes = 0;
+ ch->gr_ram_userd_park_put = pput;
+ if (ch->gr_ram_userd_park_probes < 2)
+ return false;
+ (void)svc_read_ap(vgpu, ch->gr_ram_userd_park_pa + SVC_USERD_GP_GET,
+ ch->gr_ram_userd_park_as, &pget, sizeof(pget));
+ ch->gr_ram_userd_park_probes = 0;
+ *pa_out = ch->gr_ram_userd_park_pa;
+ *put_out = pput;
+ *get_out = pget;
+ return true;
+}
+
+/*
* CONT.462 (X-DMA latch lifetime): live-latch re-probe for the DDX family.
*
* The X DDX allocates a NEW control block per push-on-demand generation and
@@ -44057,38 +44150,64 @@ static bool svc_userd_ddx_reprobe(struct nv_vgpu_device *vgpu,
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;
- if (npa == ch->userd_pa)
+ /*
+ * r1780 (eng8 clause i): adoption grace. A latch adopted 27 ms ago
+ * (c190: 0x11ab58000) must not be swapped in the same pass or within
+ * ~1 s of the adopt; the fresh block's own DMA window decides first.
+ */
+ if (ch->gr_ram_userd_adopt_at &&
+ time_before(jiffies, ch->gr_ram_userd_adopt_at +
+ msecs_to_jiffies(SVC_USERD_DDX_ADOPT_GRACE_MS)))
return false;
+ /*
+ * r1780 (eng8 clause ii): prefer the parked proven block (checked
+ * FIRST - a bounded forward PUT advance across two probes proves the
+ * client re-used/re-allocated the proven layout), else the content
+ * scan.
+ */
{
- u64 opa = ch->userd_pa;
- u32 oput = ch->gr_ram_userd_latch_put;
+ bool parked = svc_userd_ddx_park_probe(vgpu, ch, &npa, &nput,
+ &nget);
- ch->userd_pa = npa;
- ch->userd_as = SVC_APERTURE_SYS;
- ch->userd_ok = true;
- svc_kick_capture_arm(vgpu, ch, ring_pa, ring_ap, nput);
- if (ch->gpfifo_entries > 1 && nput) {
- u32 span = nput < ch->gpfifo_entries ?
- nput : ch->gpfifo_entries - 1;
-
- ch->last_get = (nput % ch->gpfifo_entries +
- ch->gpfifo_entries - span) %
- ch->gpfifo_entries;
- } else {
- ch->last_get = 0;
+ if (!parked &&
+ !svc_gr_ram_userd_scan(vgpu, ch, &npa, &nput, &nget))
+ return false;
+ if (npa == ch->userd_pa)
+ return false;
+ {
+ u64 opa = ch->userd_pa;
+ u32 oput = ch->gr_ram_userd_latch_put;
+
+ ch->userd_pa = npa;
+ ch->userd_as = parked ? ch->gr_ram_userd_park_as :
+ SVC_APERTURE_SYS;
+ ch->userd_ok = true;
+ svc_kick_capture_arm(vgpu, ch, ring_pa, ring_ap,
+ nput);
+ if (ch->gpfifo_entries > 1 && nput) {
+ u32 span = nput < ch->gpfifo_entries ?
+ nput : ch->gpfifo_entries - 1;
+
+ ch->last_get = (nput % ch->gpfifo_entries +
+ ch->gpfifo_entries - span) %
+ ch->gpfifo_entries;
+ } else {
+ ch->last_get = 0;
+ }
+ ch->gr_ram_put_seeded = nput;
+ ch->gr_ram_userd_latch_put = nput;
+ ch->gr_ram_userd_latch_at = jiffies;
+ ch->gr_ram_userd_adopt_at = jiffies;
+ ch->gr_ram_userd_latch_sub = ch->submissions;
+ ch->gr_ram_userd_defers = 0;
+ ch->gr_ram_userd_confirmed = false;
+ *put = nput;
+ *get = nget;
+ pr_info("sema-chan: GR USERD h=0x%x latch SWITCHED to %s block pa=0x%llx (put=%u get=%u; old pa=0x%llx latch=%u)\n",
+ ch->h_object,
+ parked ? "parked proven" : "re-probed",
+ npa, nput, nget, opa, oput);
}
- ch->gr_ram_put_seeded = nput;
- ch->gr_ram_userd_latch_put = nput;
- ch->gr_ram_userd_latch_at = jiffies;
- ch->gr_ram_userd_latch_sub = ch->submissions;
- ch->gr_ram_userd_defers = 0;
- ch->gr_ram_userd_confirmed = false;
- *put = nput;
- *get = nget;
- pr_info("sema-chan: GR USERD h=0x%x latch SWITCHED to re-probed block pa=0x%llx (put=%u get=%u; old pa=0x%llx latch=%u)\n",
- ch->h_object, npa, nput, nget, opa, oput);
}
return true;
}
@@ -45032,6 +45151,20 @@ static void svc_pump_channels(struct nv_vgpu_device *vgpu)
if (stepped) {
ch->gr_ram_userd_confirmed = true;
ch->gr_ram_userd_defers = 0;
+ /*
+ * r1780 (eng8 clause ii): a CONFIRMED DDX
+ * block is the proven layout - park it
+ * (pa+aperture+PUT) so the next generation's
+ * re-probe/scan checks it first.
+ */
+ if (svc_userd_ddx_family(ch)) {
+ ch->gr_ram_userd_park_pa =
+ ch->userd_pa;
+ ch->gr_ram_userd_park_as =
+ ch->userd_as;
+ ch->gr_ram_userd_park_put = put;
+ ch->gr_ram_userd_park_probes = 0;
+ }
if (wrap &&
put < ch->gr_ram_userd_latch_put)
pr_info_ratelimited("sema-chan: GR USERD h=0x%x pa=0x%llx speculative latch wrap accepted (put %u latch %u ent %u step %u)\n",
@@ -48076,6 +48209,18 @@ static void svc_pump_channels(struct nv_vgpu_device *vgpu)
ch->gr_ram_userd_reject_at;
svc.chan[k].gr_ram_userd_reprobe_at =
ch->gr_ram_userd_reprobe_at;
+ /* r1780 (eng8): adoption grace + parked
+ * proven-block state survive the snapshot. */
+ svc.chan[k].gr_ram_userd_adopt_at =
+ ch->gr_ram_userd_adopt_at;
+ svc.chan[k].gr_ram_userd_park_pa =
+ ch->gr_ram_userd_park_pa;
+ svc.chan[k].gr_ram_userd_park_as =
+ ch->gr_ram_userd_park_as;
+ svc.chan[k].gr_ram_userd_park_put =
+ ch->gr_ram_userd_park_put;
+ svc.chan[k].gr_ram_userd_park_probes =
+ ch->gr_ram_userd_park_probes;
svc.chan[k].gr_ram_userd_confirmed =
ch->gr_ram_userd_confirmed;
/* CONT.407: keep-across-put-reset state. */