diff options
| author | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-10-18 12:06:43 -0400 |
|---|---|---|
| committer | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-10-18 12:10:03 -0400 |
| commit | 2658fedd556f872f11dd3aeefa88ff6eb76c5342 (patch) | |
| tree | 7cea694eef4c4ec2e353db58a2dc37e3cf3f16fe /kernel/gsp_phys_gpu.c | |
| parent | 7fc3c3ca9f0c2e25c5a932e3fa955dcb0a261ec6 (diff) | |
| download | open-iov-2658fedd556f872f11dd3aeefa88ff6eb76c5342.tar.gz open-iov-2658fedd556f872f11dd3aeefa88ff6eb76c5342.zip | |
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)
Diffstat (limited to 'kernel/gsp_phys_gpu.c')
| -rw-r--r-- | kernel/gsp_phys_gpu.c | 35 |
1 files changed, 35 insertions, 0 deletions
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; |
