WIP: fix(vk): free a stalled shader preparation's pipeline notes #517
No reviewers
Labels
No labels
area/accessibility
area/audio
area/input
area/install
area/menu
area/renderer
area/saves
area/tooling
area/upscaling
beanstalk: approved
beanstalk: needs approval
beanstalk: running
ci: approved
good first issue
gpu/amd
gpu/igpu
gpu/intel
gpu/nvidia
help wanted
kind
bug
kind
chore
kind
docs
kind
feature
kind
performance
kind
question
needs measurements
platform/linux
platform/macos
platform/steam-deck
platform/windows
preview
priority
critical
priority
high
priority
low
regression
risk
high
risk
low
risk
medium
status
blocked
status
confirmed
status
duplicate
status
invalid
status
needs-info
status
wontfix
testing wanted
ci: approved
No milestone
No project
No assignees
3 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
MagicBeanDev/Longshot!517
Loading…
Reference in a new issue
No description provided.
Delete branch "Amateurwizrd/Longshot:fix/prepare-stall-notes"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Type: fix · Risk: low · Tested on: Windows 11, RTX 5070 Ti 16 GB (game-free) · Needs: Linux
Why
When the driver stalls a shader preparation (no progress for 30 s), the preparation gives up on its workers and never
frees the run's pipeline notes, each holding a whole
NvnState: gigabytes of host memory stay allocated for the rest ofthe session after a stalled prediction. Searched the tracker: no issue covers it.
How to reproduce
Seen on: the game-free check below, Windows 11, RTX 5070 Ti, driver 621.01; in the game it needs a driver that stalls a preparation, which could not be produced on demand here
Settings and switches: defaults
Steps: run
tests/test_prepare_abandon.py(this PR's check) against main'sgpu/vk/vk_draw.cppandgpu/vk/vk_progcache.cpp: its stand-in driver never returns from one worker's pipeline creation, and its callback throws in a borrowExpected: after the give-up every note no worker holds is freed, and a throw in
program_cache_borrow's callback leaves no module or layout aliveActual: the notes stay allocated, and the borrowed modules and layouts are left alive
What changed
The preparation's workers now share its state, so whichever finishes last frees it, and the thread that gives up frees
at once every note no stalled worker still holds. A borrow from the program cache keeps what it loaded in a guard, so a
throw leaves nothing behind.
precompile_runandpredict_runingpu/vk/vk_draw.cppshare their state with the workers, so the last workerto return frees it; the thread that gives up frees at once, under the state's lock, every note no worker holds (a
worker the driver never returns from keeps only its own note). The stall's log line says how much host memory the
notes held and how much was freed.
program_cache_borrowingpu/vk/vk_progcache.cppkeeps each variant's modules and layouts in a guard once theloader has handed it over, so a throw from the callback or a later variant's load leaves none of them behind.
tests/test_prepare_abandon.py(new) runs the real worker and borrow code with a stalled driver stand-in.The idea of sharing the state with the workers was first seen in Hookshot-old's 9553c039; freeing the notes at the
stall and the borrow guard are new, and the code is written for Longshot.
Measurements
Verdict: it passes: the new check fails on main @
13e8b6dain both runs and passes on this PR @dcd64421in both.Hardware: Windows 11 Pro 26200, RTX 5070 Ti 16 GB, driver 621.01, Ryzen 7 7800X3D, 32 GB
Scene: none (game-free check)
Method: the new test, run 2 times on each side, interleaved (main, this PR, main, this PR); main gets this PR's test file only
How to reproduce:
python -I -B tests/run_all.py prepare_abandonon this branch, and on main withtests/test_prepare_abandon.pycopied in13e8b6dadcd64421tests/test_prepare_abandon.py(run 1 / run 2)Flags and settings
None
Testing
Tested: on Windows 11 with the pinned llvm-mingw, the 124 checks that read this diff, one at a time, on this PR @
dcd64421(main @13e8b6da): 121 pass; the 3 that fail (test_linux_driver_fault_guard,test_pipeline_tour,test_vk_occlusion_queries) also fail on main @13e8b6da; none fails here that passes on main. The renderer was not built at this head.Not tested: a stalled preparation in the game: no driver stall could be produced on demand here; the new test
drives the same worker code with a stand-in driver that never returns.
Must be tested:
gpu/vk/vk_draw.cpporgpu/vk/vk_progcache.cppRisks
What could break: the preparation's teardown changes: a worker returning after the give-up now frees its own note,
so a mistake there would be a use-after-free in the preparation workers (the test covers a worker returning late and
one never returning).
Turning it off: revert the commit.
Compatibility: Nothing changes.
Checklist
Everyone
type(scope): description) of the status line's type.main.python -I -B tests/run_all.pypasses (any failure that also fails onmainis named).third_party/untouched (a new folder with aPROVENANCE.mdinstead).When it applies
Assisted-by:/Co-Authored-By:trailers.mainand passing here.11da7d46fe899490c5f4Rebased onto
main@bbe6fdf2. No tests were run here; the test boxes stay yours. No conflicts.899490c5f4dcd644215fRebased onto main @
13e8b6da(dcd64421). One new commit: main's quick compute pipelines (ae96bad3) made the preparation callprecompile_compute_quickand markProgram::optimize_owed, sotest_prepare_abandon's stubs gained both (the stub keeps the optimizer, as before). Re-measured on this main and the description moved to the current template: the new check fails on main twice and passes here twice; the 124 checks that read this diff: 121 pass, the 3 failing also fail on main.@Beanstalk linux, build the renderer at this head: it should build with no error in the files this PR changes; no change in play expected from the build alone.
@Amateurwizrd only members of
BigBeanscan start the farm. One of them can approve this request by reacting 👍 to it.View command line instructions
Checkout
From your project repository, check out a new branch and test the changes.