From 75b908eec35180c71f91450cece1b6d1f3fc5ddd Mon Sep 17 00:00:00 2001 From: Arthur Hanson Rasmusson Date: Fri, 23 Oct 2026 21:47:25 -0400 Subject: vgsp-work r583: fail-closed at the defer cap when a launch's data page still has an unexecuted device write The r581 boot's saxpy red draw (bad=524121 csum=874874129) shows the residual hole of the r541 dstpend guard: GR-DEC "push=0x20043c198 n_data=2505 dropped=8 partial=1 dstpend=1 copypend=0 defer_exp=0" and on the final dump defer_exp=1 - the launch overlapped a page whose device write had never executed (live dstpend records 9.5-85 s old), the guard deferred through its bounded retry, the r556 15 s absolute cap expired, and the historical path forwarded the launch anyway: the engine read the known-stale operand and produced the ~50%-wrong result. r583: at cap expiry with the overlap still live the forward is REFUSED. Fail-closed: the candidate's QMD completion is authored in software (forward-only; rel_done latched so the consume tail cannot double-author) and the candidate is consumed without an engine launch - the client completes, the engine never touches a page whose writer did not run, and the event is witnessed loudly ("GR forward REFUSED at defer cap ..."). This cannot hang the guest: the refusal consumes instead of holding. --- kernel/gsp_sema_service.c | 54 ++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 44 insertions(+), 10 deletions(-) (limited to 'kernel/gsp_sema_service.c') diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c index 741fdc2..151d8bf 100644 --- a/kernel/gsp_sema_service.c +++ b/kernel/gsp_sema_service.c @@ -1111,6 +1111,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_closed; /* r583: fail-closed at the defer + * cap (dstpend still live) */ + u32 fwd_gr_closed_log; u64 fwd_gr_argdefer; /* r543: held for a partial * argument set (unresolved arg) */ u32 fwd_gr_argdefer_log; @@ -21232,19 +21235,50 @@ 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() && - !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; + if (svc_gr_dstpend_overlap()) { + if (!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; + svc.fwd_gr_refused++; + svc.fwd_gr_dstpend++; + if (svc.fwd_gr_dstpend_log < 32) { + svc.fwd_gr_dstpend_log++; + pr_info("vgsp-work: GR forward deferred h=0x%x push=0x%llx (data page has an unexecuted device write; bounded retry)\n", + ch->h_object, svc_gr_cand.push_va); + } + return false; + } + /* + * r583: the absolute defer cap expired while a data page still + * overlaps a pending device write (r581 saxpy live: GR-DEC + * dstpend=1 defer_exp=1 -> forwarded anyway -> bad=524121 + * with dstpend ages 9.5-85 s). Never forward a KNOWN-stale + * operand: fail-closed - author the candidate's QMD + * completion in software (forward-only, latched so the + * consume tail cannot author it twice) and refuse the + * engine launch. The client completes; the engine stays + * away from a page whose writer never ran. Witnessed. + */ svc.fwd_gr_refused++; - svc.fwd_gr_dstpend++; - if (svc.fwd_gr_dstpend_log < 32) { - svc.fwd_gr_dstpend_log++; - pr_info("vgsp-work: GR forward deferred h=0x%x push=0x%llx (data page has an unexecuted device write; bounded retry)\n", + 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 (data page still has an unexecuted device write; fail-closed, QMD release authored in software)\n", ch->h_object, svc_gr_cand.push_va); } - return false; + 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 */ } /* * r568: the coarse companion gate - any unexecuted CE write at all -- cgit v1.2.3