summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--kernel/gsp_sema_service.c54
1 files changed, 44 insertions, 10 deletions
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