From 2658fedd556f872f11dd3aeefa88ff6eb76c5342 Mon Sep 17 00:00:00 2001 From: Arthur Hanson Rasmusson Date: Sun, 18 Oct 2026 12:06:43 -0400 Subject: vgsp: bounded GR launch completion (GR-STALL), r220 hold storm fix, churn caps Every GR launch now either completes or fails fast with a distinguishable dmesg line; no host wait in the launch/consume path can run forever. - gsp_phys_gr_wait_max_ms (new param, default 60000, clamp [10000,600000], 0 = built-in per-ladder bounds only): absolute per-launch submit budget. Checked in the GR poll loop (after the release acks) and in the retirement-retry loop; on expiry the submit fails out ('vgsp-gr: GR-STALL-wait-max ... action=fail') or the retry loop stops ('GR-STALL-retry ... action=proceed'), so the chain of individually bounded ladder phases can no longer hold the single-inflight work item (and the client's launch wait) for the ladder sum. - gsp_sema_service: pass-top svc_fwd_outcome_check() completes a forwarded GR request that no hold owns. A GR push with no push-level release records engages no release hold, so a backend failure (ladder timeout, abort) left the QMD completion word unwritten and the client waited to its own timeout (r219/r222, qmd_rel frozen at the previous value). The check authors the word in software (full resolver, forward-only, latched once) and logs 'GR-STALL-backend ... action=proceed'. It also covers a *successful* submit whose release0 could not target the guest page (engine completion landed on the module semaphore only) - the work item records gr_rel_unobserved for that. - Consume tail: a GR capture consumed without ever being forwarded (a data-stall / busy-defer / no-capture hold fell through) now authors its QMD completion release, latched per capture, and logs 'GR-STALL-hold'. - r220 hold-storm fix (196 s re-hold): the m150/m156 data-stall hold window is keyed to the GPFIFO slot index, and a pin-batch rewind replays the same launch at different slots, so the window re-armed on every pass; the absolute per-launch backstop could never fire because its record fields were excluded from the pump snapshot write-back list (the GRFIX NOTE record leak) and the fill gate defaulted off. The four bound fields are now written back and svc_gr_hold_bound_expired is effective on the default path (cap gsp_phys_gr_hold_max_ms, default 3000 ms, keyed to the launch push VA via svc_gr_launch_va so nothing re-arms it across rewinds); the busy-defer hold site consults the same bound. On expiry the entry is consumed with the software completion and logs 'GR-STALL-hold-bound'. - Hold expiry/failure edges log 'GR-STALL-fwd-hold' / 'GR-STALL-fwd-fail' with waited_ms for held forwarded launches. - Anti-degradation under pin churn/leftover clients: svc_rescue_scan_range (up to 6 GB of guest-RAM reads on the service thread) is capped at 3 s per range with RESCUE-SCAN-CAP logging; the ledger eviction burst triggers a logged wholesale cache reset (LEDGER-RESET cap-and-degrade, 256 evictions); pending-ring overflow is counted and surfaced (PENDING-OVF, pend_ovf in the drain line). New diag tokens: gr_swrel/pend_ovf, ledger resets, rescue scan_capped, work_gr stall_wait_max/stall_retry/wait_max_ms. Green behavior: normal launches complete in ~0.2-11 s and never approach the budget; the hold bound only fires where the old path could stall forever. make kernel green; only pre-existing warnings. (cherry picked from commit dc3650105f163631bb826ae3685a7d6e9025bfe8) --- kernel/gsp_phys_gpu.c | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) (limited to 'kernel/gsp_phys_gpu.c') diff --git a/kernel/gsp_phys_gpu.c b/kernel/gsp_phys_gpu.c index 9568d22..e845493 100644 --- a/kernel/gsp_phys_gpu.c +++ b/kernel/gsp_phys_gpu.c @@ -1069,6 +1069,41 @@ module_param_named(gsp_phys_gr_nowrite_retries, MODULE_PARM_DESC(gsp_phys_gr_nowrite_retries, "Dedicated re-execution budget for a data-bearing GR launch that wrote nothing tracked, clamped [0,4] (default 3)"); +/* + * STALLFREE: absolute per-launch wall-clock budget (gsp_phys_gr_wait_max_ms; + * default 60000, clamped [10000, 600000]; 0 disables the extra cap and the + * built-in ladder bounds stand alone). The GR submit ladder and its retirement + * (no-write) retries are individually bounded, but their SUM grows with every + * re-arm/re-publish: a launch whose engine ack never arrives could hold the + * single-inflight work item for tens of seconds while the guest client waits + * on its QMD completion word. When this budget is crossed the submit stops its + * ladder immediately (no further re-arm/publish/retry), logs + * 'vgsp-gr: GR-STALL-wait-max ... action=fail' and returns -ETIMEDOUT; the + * sema service's failure edge then authors the QMD completion release in + * software, so the client always completes. A green launch (~0.2-11 s end to + * end, including the fast-re-arm recovery) never approaches the default, so + * the default does not change green behavior. + */ +static unsigned int gsp_phys_gr_wait_max_ms_param = 60000u; +module_param_named(gsp_phys_gr_wait_max_ms, + gsp_phys_gr_wait_max_ms_param, uint, 0644); +MODULE_PARM_DESC(gsp_phys_gr_wait_max_ms, + "Absolute per-launch GR submit budget in ms, clamped [10000,600000]; 0 = only the built-in per-ladder bounds (default 60000)"); + +unsigned int gsp_phys_gr_wait_max_ms_value(void) +{ + unsigned int v = gsp_phys_gr_wait_max_ms_param; + + if (!v) + return 0; + if (v < 10000u) + v = 10000u; + if (v > 600000u) + v = 600000u; + return v; +} +EXPORT_SYMBOL_GPL(gsp_phys_gr_wait_max_ms_value); + int gsp_phys_gr_nowrite_retries_value(void) { int v = gsp_phys_gr_nowrite_retries_param; -- cgit v1.2.3