summaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-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);