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.c60
1 files changed, 60 insertions, 0 deletions
diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c
index f1a31df..65b8ac1 100644
--- a/kernel/gsp_sema_service.c
+++ b/kernel/gsp_sema_service.c
@@ -21149,6 +21149,65 @@ static bool svc_ce_stream_backlog(struct nv_vgpu_device *vgpu)
}
/*
+ * r598 diag: the driver's ring WRITE pointer, not the GPFIFO put. The r568
+ * draw needs the copy entries that are already written into the ring but
+ * whose GP_PUT has not been published yet. When the put says the ring is
+ * drained, peek at the slots immediately after the consumption position and
+ * log their {va,len} plus whether the slot already executed that exact
+ * entry. Bounded per launch, gated by gsp_phys_gr_peek.
+ */
+u32 gsp_phys_gr_peek;
+
+static void svc_gr_peek_lookahead(struct nv_vgpu_device *vgpu,
+ const struct svc_channel *self)
+{
+ u32 k, logged = 0;
+
+ if (!gsp_phys_gr_peek || !svc_pass_local)
+ return;
+ for (k = 0; k < svc_pass_local_n && logged < 8; k++) {
+ const struct svc_channel *c = &svc_pass_local[k];
+ u32 put = 0, j;
+
+ if (!c->valid || c->h_object == self->h_object ||
+ !c->gpfifo_va || !c->gpfifo_entries || !c->userd_pa)
+ continue;
+ if (svc_read_ap(vgpu, c->userd_pa + SVC_USERD_GP_PUT,
+ c->userd_as, &put, sizeof(put)))
+ continue;
+ put %= c->gpfifo_entries;
+ if (put != ((u32)c->last_get % c->gpfifo_entries))
+ continue; /* real published backlog */
+ pr_info("vgsp-gr: peek h=0x%x put=%u last=%u\n",
+ c->h_object, put, (u32)c->last_get);
+ for (j = 1; j <= 4; j++) {
+ u32 idx = ((u32)c->last_get + j) % c->gpfifo_entries;
+ u8 ent[SVC_GPFIFO_ENTRY_SIZE];
+ u32 e0, e1, len;
+ u64 va;
+
+ if (svc_read_va(vgpu,
+ c->gpfifo_va +
+ (u64)idx * SVC_GPFIFO_ENTRY_SIZE,
+ ent, sizeof(ent)))
+ break;
+ memcpy(&e0, ent, 4);
+ memcpy(&e1, ent + 4, 4);
+ va = ((u64)(e1 & 0xff) << 32) |
+ (u64)(e0 & 0xfffffffc);
+ len = ((e1 >> 10) & 0x1fffff) << 2;
+ if (!va || !len || len > SVC_PUSH_MAX)
+ break;
+ pr_info("vgsp-gr: peek +%u idx=%u va=0x%llx len=%u ident_match=%d\n",
+ j, idx, va, len,
+ c->slot_ops_ident[idx] ==
+ ((u64)e0 | ((u64)e1 << 32)));
+ }
+ logged++;
+ }
+}
+
+/*
* 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
@@ -21401,6 +21460,7 @@ static bool svc_gr_request(struct nv_vgpu_device *vgpu,
* historical forward stands (witnessed) - the guard delays a launch,
* it never refuses one, so it cannot recreate r588's mail refusal.
*/
+ svc_gr_peek_lookahead(vgpu, ch);
if (svc_ce_stream_backlog(vgpu)) {
if (!svc_gr_defer_expired(svc_gr_cand.push_va)) {
clear_bit_unlock(SVC_FWD_INFLIGHT, &svc_fwd_state);