summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--kernel/gsp_sema_service.c26
1 files changed, 22 insertions, 4 deletions
diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c
index 6e37b2f..0520c4f 100644
--- a/kernel/gsp_sema_service.c
+++ b/kernel/gsp_sema_service.c
@@ -425,6 +425,9 @@ struct svc_channel {
* must reconcile the binding before the walk
* (drop dead opdef slots whose since predates
* the binding; log the transition) */
+ unsigned long wd_newbind_hold_until; /* short hold window inside
+ * wd_newbind_until (residual-only,
+ * put==get; never delays fresh work) */
unsigned long wd_newbind_until; /* STALLFREE: freshness window of a
* new binding; inside it an
* unmapped/undecoded GR entry is held
@@ -16604,6 +16607,15 @@ static void svc_userd_sweep(struct nv_vgpu_device *vgpu, struct svc_channel *ch,
* window of extra latency on first contact.
*/
#define SVC_GR_NEWBIND_MS 3000u
+/*
+ * STALLFREE r237: the HOLD part of the window must be shorter than the
+ * window itself. r237-2: the 3 s hold on T2's residual ring delayed its
+ * GP_GET past the guest's ~3 s ctx-init patience (T2 unwound with a
+ * zeroed PROMOTE_CTX at binding+3.46 s, exactly when the host finally
+ * consumed the residual). The guest needs GP_GET to advance promptly;
+ * the rebuild lands in ~0.8 s, so 1.2 s is enough for one attempt.
+ */
+#define SVC_GR_NEWBIND_HOLD_MS 1200u
static void svc_gr_stale_wedge_check(struct nv_vgpu_device *vgpu,
struct svc_channel *ch, u32 put, u32 get)
@@ -17195,6 +17207,8 @@ static void svc_pump_channels(struct nv_vgpu_device *vgpu)
svc_opdef_drop_channel(vgpu, ch->h_object, jiffies);
ch->wd_newbind_until = jiffies +
msecs_to_jiffies(SVC_GR_NEWBIND_MS);
+ ch->wd_newbind_hold_until = jiffies +
+ msecs_to_jiffies(SVC_GR_NEWBIND_HOLD_MS);
/*
* Bounded proof (r234 asks): the window was armed for
* THIS binding; if a later stall shows no such line,
@@ -17719,9 +17733,10 @@ static void svc_pump_channels(struct nv_vgpu_device *vgpu)
!entry_replay &&
svc_rel_count == rel_n_iter &&
svc_gr_qmd_seen == 0 &&
- ch->wd_newbind_until &&
+ put == get &&
+ ch->wd_newbind_hold_until &&
time_before(jiffies,
- ch->wd_newbind_until)) {
+ ch->wd_newbind_hold_until)) {
if (!ch->defer_since)
ch->defer_since =
jiffies;
@@ -18805,9 +18820,10 @@ static void svc_pump_channels(struct nv_vgpu_device *vgpu)
* the rebuild caught up).
*/
if (!ch->engine_type &&
- ch->wd_newbind_until &&
+ put == get &&
+ ch->wd_newbind_hold_until &&
time_before(jiffies,
- ch->wd_newbind_until)) {
+ ch->wd_newbind_hold_until)) {
svc.rebuild_now = true;
if (svc.gr_pending_map < 16) {
svc.gr_pending_map++;
@@ -19045,6 +19061,8 @@ static void svc_pump_channels(struct nv_vgpu_device *vgpu)
svc.chan[k].wd_nocap_put = ch->wd_nocap_put;
svc.chan[k].wd_chanswitch = ch->wd_chanswitch;
svc.chan[k].wd_newbind_until = ch->wd_newbind_until;
+ svc.chan[k].wd_newbind_hold_until =
+ ch->wd_newbind_hold_until;
svc.chan[k].pushpg_va = ch->pushpg_va;
svc.chan[k].pushpg_n = ch->pushpg_n;
svc.chan[k].content_max = ch->content_max;