From 154ac292a2a93a990ab4f8588d708f24171092a6 Mon Sep 17 00:00:00 2001 From: Arthur Hanson Rasmusson Date: Fri, 16 Oct 2026 14:23:22 -0400 Subject: 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. --- kernel/gsp_sema_service.c | 56 ++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 50 insertions(+), 6 deletions(-) (limited to 'kernel/gsp_sema_service.c') 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); -- cgit v1.2.3