summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-16 14:23:22 -0400
committerArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-16 14:23:22 -0400
commit154ac292a2a93a990ab4f8588d708f24171092a6 (patch)
treee2b3b80dc591ce645b305b33af2b2ca9a5b93fad
parent79e1f459301849e57baffc0e796df32b2aeb8124 (diff)
downloadopen-iov-154ac292a2a93a990ab4f8588d708f24171092a6.tar.gz
open-iov-154ac292a2a93a990ab4f8588d708f24171092a6.zip
vgsp-sema: m158 make GR busy-defer holds survive and force re-capture (R1 continuation)
r158: the m156 hold fired (entries held, no fabricated release) but the held entry's next decode is a replay, which suppresses the launch capture, and the one-shot hold flag consumed the entry on the following pass - the deferred launches were still lost (channel unregistered before they ran). Two changes: - the hold now stays armed for its whole window (re-hold while time_before(gr_hold_until)) instead of one-shot per slot; - the hold arms ch->gr_rehold_idx, and the entry decode forces exactly one fresh (non-replay) pass for that slot with ops still suppressed and the capture re-enabled, so the deferred launch is captured and forwarded for real once the engine's in-flight launch completes.
-rw-r--r--kernel/gsp_sema_service.c56
1 files changed, 50 insertions, 6 deletions
diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c
index 79807ab..53b8288 100644
--- a/kernel/gsp_sema_service.c
+++ b/kernel/gsp_sema_service.c
@@ -347,7 +347,14 @@ struct svc_channel {
u32 gr_hold_idx; /* GPFIFO slot the window was armed for (identity:
* an entry holds at most once, then is consumed
* even if still unresolved - bounded zeros, never
- * a hang) */
+ * a hang); m156: re-held while the window is
+ * live so a busy forward gets its real retry */
+ u32 gr_rehold_idx; /* m156: slot whose next decode must force a
+ * fresh launch capture (a held entry is
+ * re-decoded as a replay, which suppresses
+ * the capture; forcing it lets a deferred
+ * launch be forwarded once the engine's
+ * in-flight work completes) */
};
/*
@@ -1185,6 +1192,8 @@ void gsp_sema_service_channel_add(const struct sema_channel_desc *desc)
}
memset(ch, 0, sizeof(*ch));
+ ch->gr_hold_idx = ~0u; /* m156: no hold armed yet */
+ ch->gr_rehold_idx = ~0u;
if (same)
bitmap_copy(ch->rel_done, keep_rel_done,
SVC_GPFIFO_MAX_BITS);
@@ -14376,6 +14385,22 @@ static void svc_pump_channels(struct nv_vgpu_device *vgpu)
{
u32 rel_n_before = svc_rel_count;
bool rel_seen;
+ /*
+ * m156: this entry is inside a live
+ * GR hold window and its decode is a
+ * replay that would suppress the
+ * launch capture. Force exactly one
+ * fresh capture pass (ops stay
+ * suppressed: they already ran; only
+ * the candidate build is re-done) so
+ * the deferred launch is forwarded
+ * for real once the engine's
+ * in-flight work completes.
+ */
+ bool rehold =
+ !ch->engine_type &&
+ ch->gr_rehold_idx ==
+ (u32)idx;
svc_entry_outcome("decode", ch,
idx, va, len);
@@ -14383,15 +14408,18 @@ static void svc_pump_channels(struct nv_vgpu_device *vgpu)
svc_decode_stream(vgpu, pb,
len, 0,
(allow_ops || injected) &&
- !entry_replay,
+ !entry_replay &&
+ !rehold,
ch,
idx,
va,
- injected,
- entry_replay,
- entry_replay ?
+ injected || rehold,
+ entry_replay && !rehold,
+ (entry_replay && !rehold) ?
NULL :
&entry_done);
+ if (rehold)
+ ch->gr_rehold_idx = ~0u;
/*
* Record what ran for this entry
* identity before any hold path can
@@ -14523,10 +14551,26 @@ static void svc_pump_channels(struct nv_vgpu_device *vgpu)
!ch->engine_type &&
(svc_gr_data_stalled ||
svc_gr_busy_defer) &&
- ch->gr_hold_idx != (u32)idx) {
+ (ch->gr_hold_idx != (u32)idx ||
+ time_before(jiffies,
+ ch->gr_hold_until))) {
u32 hold_ms = gsp_sema_gr_grace_ms ?
gsp_sema_gr_grace_ms : 8000;
+ /*
+ * m156: arm the forced
+ * re-capture so the next
+ * decode of this entry
+ * rebuilds the GR candidate
+ * (a replay decode would
+ * suppress it) and the
+ * deferred launch is
+ * forwarded for real once
+ * the in-flight work has
+ * completed.
+ */
+ ch->gr_rehold_idx =
+ (u32)idx;
ch->gr_hold_idx = (u32)idx;
ch->gr_hold_until = jiffies +
msecs_to_jiffies(hold_ms);