diff options
| author | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-11-13 01:35:20 -0500 |
|---|---|---|
| committer | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-11-13 01:35:20 -0500 |
| commit | 296906351bc671e60a3dfbbad8eae3e667227195 (patch) | |
| tree | e5f4a003768f24e673ac2572ff1c058fce968c60 | |
| parent | b9213c57222026eacc41dbcec079190c27f7e111 (diff) | |
| download | open-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.c | 209 |
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. */ |
