summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--kernel/gsp_sema_service.c65
1 files changed, 65 insertions, 0 deletions
diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c
index af2d056..c575379 100644
--- a/kernel/gsp_sema_service.c
+++ b/kernel/gsp_sema_service.c
@@ -1108,6 +1108,9 @@ struct sema_svc {
u64 fwd_gr_dstpend; /* r541: held for an unexecuted
* device write on a data page */
u32 fwd_gr_dstpend_log;
+ u64 fwd_gr_argdefer; /* r543: held for a partial
+ * argument set (unresolved arg) */
+ u32 fwd_gr_argdefer_log;
u64 fwd_gr_timeout;
u64 fwd_gr_fault;
u64 fwd_gr_bridge;
@@ -16619,6 +16622,14 @@ struct svc_fwd_req {
u32 gr_dropped; /* GRFIX: pages the fill's last pass could not
* resolve (0 = launch fully resolved); read
* by the absolute-bound expiry log */
+ bool gr_arg_partial; /* r543: an ARGUMENT pointer resolved 0
+ * pages while other arguments resolved - the
+ * launch would run with a stale/zero operand
+ * (the r542 matmul NOWRITE wedge: fe_esr=
+ * 0x80000000, engine fetch OK, wrote 0,
+ * client read zeros). The request path holds
+ * such a launch once per push VA through the
+ * bounded busy-defer retry. */
u64 gr_push_va;
u32 gr_push_len;
u32 gr_push_n;
@@ -19724,6 +19735,7 @@ static void svc_gr_data_fill(struct nv_vgpu_device *vgpu,
svc_fwd_req.gr_n_data = 0;
svc_fwd_req.gr_dropped = 0;
+ svc_fwd_req.gr_arg_partial = false;
svc_fwd_req.gr_n_data_wins = 0;
svc_gr_data_stalled = false;
memset(is_arg, 0, sizeof(is_arg));
@@ -20055,6 +20067,8 @@ static void svc_gr_data_fill(struct nv_vgpu_device *vgpu,
* page).
*/
svc_log_stalled_va(va);
+ if (is_arg[w])
+ svc_fwd_req.gr_arg_partial = true;
if (dropped_pages < 4) {
drop_va[dropped_pages] = va;
drop_kind[dropped_pages] =
@@ -20493,6 +20507,30 @@ static void svc_gr_req_bridge_fallback(struct nv_vgpu_device *vgpu)
static void svc_handle_map_add(void);
/*
+ * r543: one bounded deferral per push VA for a partially-resolved argument
+ * set (see svc_fwd_req.gr_arg_partial). The latch keeps a genuine junk
+ * pointer word from adding a retry window to every launch: the first time a
+ * push is seen with a partial argument set it is deferred (pins land within
+ * ~1-2 s in the healthy case); the same push VA seen again inside the
+ * window proceeds through the historical forward. A re-used ring slot after
+ * the window gets its own deferral.
+ */
+#define SVC_GR_ARG_DEFER_MS 30000u
+static u64 svc_gr_arg_last_va;
+static unsigned long svc_gr_arg_last_j;
+
+static bool svc_gr_arg_defer_ok(u64 push_va)
+{
+ if (push_va == svc_gr_arg_last_va &&
+ time_before(jiffies, svc_gr_arg_last_j +
+ msecs_to_jiffies(SVC_GR_ARG_DEFER_MS)))
+ return false;
+ svc_gr_arg_last_va = push_va;
+ svc_gr_arg_last_j = jiffies;
+ return true;
+}
+
+/*
* r541: does any of the filled launch's data pages carry an unexecuted
* device write (see svc_dstpend_note)? Runs on the service thread right
* after the fill, so svc_fwd_req.gr_data holds this launch's records.
@@ -20631,6 +20669,33 @@ static bool svc_gr_request(struct nv_vgpu_device *vgpu,
return false;
}
/*
+ * r543: a partially-resolved ARGUMENT set must not forward either -
+ * the engine would run with a stale/zero operand (the r542 matmul
+ * wedge: 2 of 13 high arg bases resolved 0 pages, the fill proceeded
+ * "fill hold disabled (log-only)", the engine fetched the QMD and
+ * wrote nothing: NOWRITE-AMBIGUOUS fe_esr=0x80000000, client read
+ * zeros). Defer once per push VA through the bounded busy-defer
+ * retry so the pins can land; the latch (svc_gr_arg_defer_ok) keeps
+ * a genuinely junk pointer word from paying the window on every
+ * launch. After the retry the historical forward stands - the guard
+ * delays, it cannot hang.
+ */
+ if (svc_fwd_req.gr_arg_partial && !svc_gr_data_stalled &&
+ svc_gr_arg_defer_ok(svc_gr_cand.push_va)) {
+ clear_bit_unlock(SVC_FWD_INFLIGHT, &svc_fwd_state);
+ mutex_unlock(&svc_fwd_lock);
+ svc_gr_busy_defer = true;
+ svc.fwd_gr_refused++;
+ svc.fwd_gr_argdefer++;
+ if (svc.fwd_gr_argdefer_log < 32) {
+ svc.fwd_gr_argdefer_log++;
+ pr_info("vgsp-work: GR forward deferred h=0x%x push=0x%llx (partial argument set: %u page(s) unresolved; bounded retry)\n",
+ ch->h_object, svc_gr_cand.push_va,
+ svc_fwd_req.gr_dropped);
+ }
+ return false;
+ }
+ /*
* m150: the fill found high argument pointers that no source can
* translate (the second-client zeros class). Do NOT forward a launch
* whose kernel would dereference unresolved pointers: leave the