summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--kernel/gsp_sema_service.c34
-rw-r--r--tools/guest-diag/guest_pin_stream.py26
2 files changed, 60 insertions, 0 deletions
diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c
index 24cb034..e86c463 100644
--- a/kernel/gsp_sema_service.c
+++ b/kernel/gsp_sema_service.c
@@ -21375,6 +21375,40 @@ static bool svc_gr_request(struct nv_vgpu_device *vgpu,
return false;
}
/*
+ * r586: the defer cap expired with argument pages still unresolved -
+ * fail-closed like the r583 dstpend cap. The historical path
+ * forwarded the launch with the partial set and the engine read
+ * stale/zero operands (r585 boot saxpy: n_data=969 dropped=7
+ * partial=1 -> forwarded at the cap -> bad=1047527 csum=130523290;
+ * r584 matmul: n_data=2 dropped=18 -> r564 degenerate refusal ->
+ * no-write). Refuse the forward, author the completion in software,
+ * consume; the dropped pages were already demanded through the pin
+ * channel (r585) so the retry path had its chance first.
+ */
+ if (svc_fwd_req.gr_arg_partial && !svc_gr_data_stalled &&
+ svc_gr_defer_expired(svc_gr_cand.push_va)) {
+ svc.fwd_gr_refused++;
+ svc.fwd_gr_closed++;
+ if (svc_gr_cand.rel_va) {
+ svc_gr_sw_release(vgpu, ch->h_object,
+ svc_gr_cand.rel_va,
+ svc_gr_cand.rel_payload);
+ svc_gr_cand.rel_done = true;
+ }
+ svc_gr_cand.offered = true;
+ svc_gr_cand.valid = false;
+ if (svc.fwd_gr_closed_log < 32) {
+ svc.fwd_gr_closed_log++;
+ pr_warn("vgsp-work: GR forward REFUSED at defer cap h=0x%x push=0x%llx (argument pages still unresolved: %u; fail-closed, QMD release authored in software)\n",
+ ch->h_object, svc_gr_cand.push_va,
+ svc_fwd_req.gr_dropped);
+ }
+ clear_bit_unlock(SVC_FWD_INFLIGHT, &svc_fwd_state);
+ mutex_unlock(&svc_fwd_lock);
+ return false; /* no busy-defer: the pump consumes; the
+ * candidate is owned and sw-completed */
+ }
+ /*
* 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
diff --git a/tools/guest-diag/guest_pin_stream.py b/tools/guest-diag/guest_pin_stream.py
index b56f79d..175ed23 100644
--- a/tools/guest-diag/guest_pin_stream.py
+++ b/tools/guest-diag/guest_pin_stream.py
@@ -1819,6 +1819,32 @@ def main():
except Exception:
ok = False
got = []
+ # r586: a demanded VA outside the CE
+ # pushbuffer window (the GRFILL staging pages,
+ # high client VAs) is a plain client mapping
+ # page: resolve it through the client's own
+ # pagemap. Without this the demand for those
+ # VAs was a silent no-op (resolve_va_by_content
+ # rejects anything outside PB_CE_LO..PB_CE_HI)
+ # and the fills kept dropping them.
+ if not ok and not got and pid:
+ try:
+ pfd = os.open('/proc/%d/pagemap' % pid,
+ os.O_RDONLY)
+ try:
+ sub = {}
+ vpg = wv & ~0xFFF
+ scan_range(pfd, vpg, vpg + 0x1000,
+ sub)
+ finally:
+ os.close(pfd)
+ if sub:
+ for v, p in sub.items():
+ got.append('0x%x,0x%x,1\n'
+ % (v, p))
+ ok = True
+ except OSError:
+ pass
if ok and got:
lines.extend(got)
_want_state["done"].add(wv)