summaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/gsp_sema_service.c43
1 files changed, 41 insertions, 2 deletions
diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c
index b2cf8a5..a3366ba 100644
--- a/kernel/gsp_sema_service.c
+++ b/kernel/gsp_sema_service.c
@@ -20705,6 +20705,42 @@ static bool svc_gr_arg_defer_ok(u64 push_va)
}
/*
+ * r556: the ABSOLUTE per-launch deferral cap. Every defer path (r541
+ * dstpend, r543 partial args, m150 data-stalled hold, busy-defer re-holds)
+ * is individually bounded, but the bounds interact and re-arm across
+ * re-decode passes; the r553/r555 boots show clients still walking these
+ * loops for 400+ s (victory_reduce 430 s, victory_saxpy 254 s at write
+ * time, work_guard deferred climbing by the thousand). This is the single
+ * backstop that makes "a launch can never be deferred for more than
+ * SVC_GR_DEFER_CAP_MS" true regardless of which guard keeps winning: the
+ * first sighting of a push VA arms an absolute deadline; once it passes,
+ * svc_gr_defer_expired() returns true and every defer site forwards
+ * best-effort. 15 s is well above the 0.5-2 s pin latency the deferrals
+ * exist to cover and well below every client-side timeout (>= 60 s).
+ */
+#define SVC_GR_DEFER_CAP_MS 15000u
+static u64 svc_gr_defer_cap_va[SVC_GR_ARG_DEFER_SLOTS];
+static unsigned long svc_gr_defer_cap_j[SVC_GR_ARG_DEFER_SLOTS];
+static u32 svc_gr_defer_cap_pos;
+
+static bool svc_gr_defer_expired(u64 push_va)
+{
+ u32 i;
+
+ if (!push_va)
+ return false;
+ for (i = 0; i < SVC_GR_ARG_DEFER_SLOTS; i++) {
+ if (svc_gr_defer_cap_va[i] == push_va)
+ return !time_before(jiffies, svc_gr_defer_cap_j[i] +
+ msecs_to_jiffies(SVC_GR_DEFER_CAP_MS));
+ }
+ i = svc_gr_defer_cap_pos++ % SVC_GR_ARG_DEFER_SLOTS;
+ svc_gr_defer_cap_va[i] = push_va;
+ svc_gr_defer_cap_j[i] = jiffies;
+ return false;
+}
+
+/*
* r548: is a forward still OWED for this push VA - a captured, never
* offered candidate sitting in the candidate ring? The r547 saxpy stall:
* both launches were deferred by the r541/r543 guards, the candidate ring
@@ -20887,7 +20923,8 @@ static bool svc_gr_request(struct nv_vgpu_device *vgpu,
* busy-defer + gr_hold machinery as every other busy refusal, so it
* can never hang the launch.
*/
- if (svc_gr_dstpend_overlap()) {
+ if (svc_gr_dstpend_overlap() &&
+ !svc_gr_defer_expired(svc_gr_cand.push_va)) {
clear_bit_unlock(SVC_FWD_INFLIGHT, &svc_fwd_state);
mutex_unlock(&svc_fwd_lock);
svc_gr_busy_defer = true;
@@ -20913,6 +20950,7 @@ static bool svc_gr_request(struct nv_vgpu_device *vgpu,
* delays, it cannot hang.
*/
if (svc_fwd_req.gr_arg_partial && !svc_gr_data_stalled &&
+ !svc_gr_defer_expired(svc_gr_cand.push_va) &&
svc_gr_arg_defer_ok(svc_gr_cand.push_va)) {
clear_bit_unlock(SVC_FWD_INFLIGHT, &svc_fwd_state);
mutex_unlock(&svc_fwd_lock);
@@ -20978,7 +21016,8 @@ static bool svc_gr_request(struct nv_vgpu_device *vgpu,
}
}
}
- if (svc_gr_data_stalled) {
+ if (svc_gr_data_stalled &&
+ !svc_gr_defer_expired(svc_gr_cand.push_va)) {
clear_bit_unlock(SVC_FWD_INFLIGHT, &svc_fwd_state);
mutex_unlock(&svc_fwd_lock);
svc.fwd_gr_refused++;