summaryrefslogtreecommitdiffstats
path: root/kernel/gsp_sema_service.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/gsp_sema_service.c')
-rw-r--r--kernel/gsp_sema_service.c68
1 files changed, 68 insertions, 0 deletions
diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c
index fbc0772..dfe7c3f 100644
--- a/kernel/gsp_sema_service.c
+++ b/kernel/gsp_sema_service.c
@@ -20986,6 +20986,65 @@ static bool svc_copy_pending(void)
return pending;
}
+/*
+ * r576 DIAG: the GR launch-decision witness (gsp_phys_gr_dec_log=N budget
+ * per boot). Logged from svc_gr_request right after the fill, for launches
+ * whose fill saw dropped pages / a partial argument set or whose decision
+ * point carries a dstpend/copy-pending verdict - i.e. exactly the draws the
+ * r566/r567/r568 guards can defer or (on their blind spots) forward. The
+ * data-page list is the operand evidence: each VA -> guest PA the engine
+ * will read; a wrong-but-valid PA here (vs the page the client's H2D wrote
+ * for the same VA) is the failure mechanism the readback lottery draws.
+ */
+unsigned gsp_phys_gr_dec_log_max;
+static unsigned svc_gr_dec_log;
+
+static void svc_gr_dec_dump(const struct svc_channel *ch)
+{
+ bool dstpend, copypend;
+ u32 i, n = 0;
+
+ if (svc_gr_dec_log >= gsp_phys_gr_dec_log_max)
+ return;
+ svc_gr_dec_log++;
+
+ dstpend = svc_gr_dstpend_overlap();
+ copypend = svc_copy_pending();
+
+ pr_info("vgsp-gr: GR-DEC h=0x%x push=0x%llx n_data=%u dropped=%u partial=%d stalled=%d dstpend=%d copypend=%d defer_exp=%d\n",
+ ch->h_object, svc_gr_cand.push_va, svc_fwd_req.gr_n_data,
+ svc_fwd_req.gr_dropped,
+ svc_fwd_req.gr_arg_partial ? 1 : 0,
+ svc_gr_data_stalled ? 1 : 0,
+ dstpend ? 1 : 0, copypend ? 1 : 0,
+ svc_gr_defer_expired(svc_gr_cand.push_va) ? 1 : 0);
+
+ for (i = 0; i < svc_fwd_req.gr_n_data && i < 32; i++)
+ pr_info("vgsp-gr: GR-DEC data[%u] va=0x%llx pa=0x%llx ap=%u reloc=0x%llx\n",
+ i, svc_fwd_req.gr_data[i].va,
+ svc_fwd_req.gr_data[i].pa, svc_fwd_req.gr_data[i].ap,
+ svc_fwd_req.gr_data[i].reloc_va);
+
+ for (i = 0, n = 0; i < svc_dstpend_n && n < 16; i++) {
+ if (!svc_dstpend[i].va_page)
+ continue;
+ n++;
+ pr_info("vgsp-gr: GR-DEC dstpend va=0x%llx age_ms=%u\n",
+ svc_dstpend[i].va_page,
+ jiffies_to_msecs(jiffies - svc_dstpend[i].since));
+ }
+
+ for (i = 0, n = 0; i < SVC_OPDEF_SLOTS && n < 8; i++) {
+ if (!svc_opdef[i].active || !svc_opdef[i].n)
+ continue;
+ n++;
+ pr_info("vgsp-gr: GR-DEC opdef h=0x%x entry=%u n=%u age_ms=%u\n",
+ svc_opdef[i].h_object, svc_opdef[i].entry_idx,
+ svc_opdef[i].n,
+ jiffies_to_msecs(jiffies - svc_opdef[i].since));
+ }
+}
+
static bool svc_gr_request(struct nv_vgpu_device *vgpu,
const struct svc_channel *ch)
{
@@ -21084,6 +21143,15 @@ static bool svc_gr_request(struct nv_vgpu_device *vgpu,
return false;
}
/*
+ * r576 DIAG: witness the decision inputs of the draws the guards
+ * care about (see svc_gr_dec_dump).
+ */
+ if (gsp_phys_gr_dec_log_max &&
+ (svc_fwd_req.gr_dropped > 0 || svc_fwd_req.gr_arg_partial ||
+ svc_gr_data_stalled || svc_gr_dstpend_overlap() ||
+ svc_copy_pending()))
+ svc_gr_dec_dump(ch);
+ /*
* r541: launch-ordering guard. The fill's data pages are what the
* engine will read; if any of them is the target of a device copy
* that decoded but has NOT executed yet (svc_dstpend_note - the