summaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-24 08:20:05 -0400
committerArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-24 08:20:23 -0400
commit0c86f3ef2ad8629f2ed392c3a24cd4ea82fc2e5f (patch)
tree1ca6f7d96da9403be583702336c0bef8c5911810 /kernel
parent46a9e2b9baf786f6e01c50c56081e3dc5eac1e33 (diff)
downloadopen-iov-0c86f3ef2ad8629f2ed392c3a24cd4ea82fc2e5f.tar.gz
open-iov-0c86f3ef2ad8629f2ed392c3a24cd4ea82fc2e5f.zip
vgsp-sema r613: a wait-gate give-up is deferred while a GR forward is owed - the release sits behind our own launch deferral
The r34x acquire wait gate gives up (fail-open, ops run) after gsp_sema_wait_hold_ms with no satisfiable value, on the premise that the value cannot be installed by firmware alone. That premise is false while we are holding the launch that authors the release: the r612 streams2 capture gave up the D2H readback's acquire (ch=0x5c00005f va=0x20480ffe0 op=3 pay=4 cur=2 waited_ms=10333) while the vadd launches that release that semaphore sat deferred by the CE watermark for the full 15 s cap; the readback then ran BEFORE the kernels and the client read zeros (STREAMS bad=65534 even with the launches forwarded and GUEST GR LAUNCH OK). While any captured candidate is still unoffered (svc_gr_forward_pending), extend the episode up to wait-hold + SVC_GR_DEFER_CAP_MS + 5 s margin and log 'extend' instead of giving up. Every client-side timeout is >= 60 s, so a <= 24 s episode cannot strand the client; when no forward is pending the give-up is unchanged.
Diffstat (limited to 'kernel')
-rw-r--r--kernel/gsp_sema_service.c100
1 files changed, 82 insertions, 18 deletions
diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c
index c0be131..27818b8 100644
--- a/kernel/gsp_sema_service.c
+++ b/kernel/gsp_sema_service.c
@@ -4656,6 +4656,16 @@ static u32 svc_wait_ovf; /* acquires dropped past the array */
static u64 svc_wait_held;
static u64 svc_wait_pass;
static u64 svc_wait_giveup;
+static u64 svc_wait_extended; /* r613: give-up deferred while a
+ * GR forward is owed */
+static u32 svc_wait_ext_log;
+/*
+ * r613: episode extension bound while a GR forward is owed. Comfortably
+ * above wait-hold (default 4000 ms) + the absolute launch defer cap
+ * (SVC_GR_DEFER_CAP_MS, 15000 ms) + margin, and far below every client-side
+ * timeout (>= 60 s).
+ */
+#define SVC_WAIT_EXT_CAP_MS 25000u
static u32 svc_wait_log; /* per-session held-row print budget */
static u32 svc_wait_pass_log; /* per-session resolved-row budget */
static u32 svc_remapconst_log; /* r343 FILL: SET_REMAP_CONST_A rows */
@@ -5968,6 +5978,29 @@ struct svc_gr_cand_rec {
static struct svc_gr_cand_rec svc_gr_cand_ring[SVC_GR_CAND_RING];
static u32 svc_gr_cand_pos;
#define svc_gr_cand (svc_gr_cand_ring[svc_gr_cand_pos])
+
+/*
+ * r613: is a GR forward owed for this device - a captured candidate that has
+ * not been offered (submitted or refused) yet? The wait gate uses this to
+ * distinguish "the acquire's release can never be installed by firmware
+ * alone" from "the release is pending behind OUR OWN launch deferral": the
+ * r612 streams2 capture gave up a D2H readback's acquire (0x20480ffe0 pay=4,
+ * cur=2) at waited_ms=10333 while the vadd launches that author that
+ * semaphore sat deferred by the CE watermark for the full 15 s cap - the
+ * readback then ran BEFORE the kernels and the client read zeros
+ * (bad=65534). While a forward is owed, the episode extends (bounded by
+ * wait-hold + defer cap + margin) instead of failing open.
+ */
+static bool svc_gr_forward_pending(void)
+{
+ u32 i;
+
+ for (i = 0; i < SVC_GR_CAND_RING; i++)
+ if (svc_gr_cand_ring[i].valid &&
+ !svc_gr_cand_ring[i].offered)
+ return true;
+ return false;
+}
/*
* r383: push-VA history of recent captures, beyond the (four-slot)
* candidate ring's lifetime. A replayed decode of a complete QMD asks
@@ -8241,26 +8274,57 @@ static void svc_run_ops(struct nv_vgpu_device *vgpu, struct svc_memset_op *ops,
pend = svc_wait_pend_release(w->va);
if (waited_ms >= gsp_sema_wait_hold_ms) {
/*
- * Bounded episode expired: fail open for the
- * WHOLE entry (one row, then the ops run). A
- * per-wait continue here would ping-pong
- * with a second unsatisfied wait: the first
- * gave up and reset the shared clock before
- * the second was judged, and the pair would
- * hold forever 100 ms at a time.
+ * r613: a deferred GR launch extends the
+ * episode. The release this acquire waits for
+ * may be authored by a launch we are holding
+ * through our own bounded deferral (the r612
+ * streams2 capture: the D2H readback's
+ * acquire on 0x20480ffe0 was given up at
+ * waited_ms=10333 while the vadd launches
+ * that release it sat deferred by the CE
+ * watermark for 15 s; the readback then ran
+ * before the kernels and the client read
+ * zeros). While a captured candidate is
+ * unoffered, "the value cannot be installed
+ * by firmware alone" is not yet true - keep
+ * holding, bounded by the defer cap plus
+ * margin. The client-side timeouts are all
+ * >= 60 s, so a <= 24 s episode cannot
+ * strand it.
*/
- svc_wait_giveup++;
- if (svc_wait_log < 2048) {
- svc_wait_log++;
- pr_info("sema-wait: give-up ch=0x%x va=0x%llx op=%u pay=%u cur=%u pend=%u waited_ms=%u -> fail-open (cannot be satisfied by firmware alone; ops run)\n",
- ch_h, w->va, w->op, w->payload,
- cur, pend, waited_ms);
+ if (waited_ms < SVC_WAIT_EXT_CAP_MS &&
+ svc_gr_forward_pending()) {
+ svc_wait_extended++;
+ if (svc_wait_ext_log < 32) {
+ svc_wait_ext_log++;
+ pr_info("sema-wait: extend ch=0x%x va=0x%llx op=%u pay=%u cur=%u waited_ms=%u -> hold (a GR forward is owed; the release is behind our own defer)\n",
+ ch_h, w->va, w->op,
+ w->payload, cur,
+ waited_ms);
+ }
+ } else {
+ /*
+ * Bounded episode expired: fail open for the
+ * WHOLE entry (one row, then the ops run). A
+ * per-wait continue here would ping-pong
+ * with a second unsatisfied wait: the first
+ * gave up and reset the shared clock before
+ * the second was judged, and the pair would
+ * hold forever 100 ms at a time.
+ */
+ svc_wait_giveup++;
+ if (svc_wait_log < 2048) {
+ svc_wait_log++;
+ pr_info("sema-wait: give-up ch=0x%x va=0x%llx op=%u pay=%u cur=%u pend=%u waited_ms=%u -> fail-open (cannot be satisfied by firmware alone; ops run)\n",
+ ch_h, w->va, w->op, w->payload,
+ cur, pend, waited_ms);
+ }
+ if (gh)
+ gh->active = false;
+ hold = false;
+ svc_wait_pass++;
+ goto svc_wait_done;
}
- if (gh)
- gh->active = false;
- hold = false;
- svc_wait_pass++;
- goto svc_wait_done;
}
hold = true;
if (svc_wait_log < 512) {