Repository navigation
Conversation
…d of freezing the Mac A session of Ocarina of Time ended in a GPU out-of-memory and a stuck game, and seedds#1326 reports a Mac frozen until the power button: GPU memory is wired, IOGPUScheduler's freeToWireMemory fails at recommendedMaxWorkingSetSize, and the submit thread then waits in the kernel where the process cannot be killed. Nothing in the host looked at the working set. res_commit now reads the larger of the set's allocatedSize and the device's currentAllocatedSize before it commits; the set's size leaves out what was never committed (measured: a new 64 MB texture adds 0 to it until the commit), the device's counts it from its creation. From 80% of the working set the submit thread lets go of what can go: idle sharing entries nothing holds, finished deferred releases, spares and the upload slots' staging. From 95%, if that was not enough, the game stops with a [RED] report of what the set holds, by kind. A commit that adds to the set is not made at the working set itself. A 100 ms timer reads the sizes too, as a stuck submit thread never comes back to look. The stop reaches the launcher as a normal exit: the Mac app closes the graphics gate, leaves full screen, shows an alert and quits as Cmd-Q does, the path PucaVaz's PR seedds#1332 takes for a revoked GPU (front_stop_alert is written so front_gpu_lost can call it); without a window the host takes its graceful exit. DM_NVN_RES_LIMIT_MB and the report's distinct pages and texture formats come from JioChoi's PR seedds#1319, moved from after the commit to before it. iOS only evicts unless the switch sets a limit: no iPhone has tried the stop. t_res_guard covers the levels, the commit refused and removals passing, what stays (a live object, the parent of a live sRGB view, a recent lookup), the second look at the stop level, and the timer with the lock held.
… the likely cause of the freeze after a window switch Ocarina of Time out of focus went from 11 to 20 GB of GPU allocated in 12 s with the residency set flat, and swap grew 6.7 GB in 20 s until boot.sh killed the run. Out of focus the game's main thread waits in oe::PopNotificationMessage (main+0x3bc0354) and submits nothing, while its streaming threads remake a run of about 10 MB of a virtual pool 70 times a second. Each old buffer went to the deferred queue behind a fence no submission would pass, and only a submission's feedback drains that queue: 770 MB a second, 881 buffers at the end of the log. A user's session froze for good at a window switch, frames not back at focus 1, audio on, no GPU error: past the working set the next commit is what the driver refuses, and DM_FOCUS_KEEP=1, which keeps the game submitting, avoids it. It also fits the sawtooth of GPU allocated noted in earlier logs. A pool's buffer retired with no submission open now waits only for what was committed, as none can reach it once it left the table, and the guard's 100 ms timer drains the queue while no feedback is due (defer_idle). The timer runs with the guard off too. The guard also counts what res_add added since the last commit, as the set's size leaves that out and the device's size could lag it. DM_CTL "focus <n>" sets the focus state, which a windowless boot needs to test this. t_res_guard: a retired pool buffer goes at the next tick between submissions, and behind the submission with one open.
Only the generated symptom index conflicted; regenerated (docs_symptoms.py). Checked: test_docs.py, docs_symptoms.py --check. No code conflict.
…ed size The device's currentAllocatedSize counts every no-copy buffer whole. With large pools in lookup chunks, pool-table segments and sparse-run buffers (seedds#1407), several lie over the same guest pages: PRAGMATA's boot load read 8,134 MB there with the residency set near 3 GB on an 8 GB Mac, and the guard's wall refused the residency commits the game needed. seedds#1392 already counts what res_add adds before a commit, which is why seedds#1391 read the device's size. DM_NVN_GUARD_DEVICE=1 keeps the old measure; the wall line prints both. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DeVTtdCXD7t64Ek6e1py6A
…r its next commit seedds#1392's g_guard_set counts what res_add adds before a commit but not what res_remove takes out, so a load that retires and replaces buffers in one burst looked like it only grew: PRAGMATA's guard stopped the game at 5,555 MB on an 8 GB Mac while the committed set never passed 4,220 MB. t_res_guard checks that a pending removal comes off. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DeVTtdCXD7t64Ek6e1py6A
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DeVTtdCXD7t64Ek6e1py6A
3 tasks done
1 task done
gnosticgeek
added a commit
to gnosticgeek/nxforge
that referenced
this pull request
Nov 9, 2026
0.23.1: GPU memory guard measures the residency set (upstream PR seedds#1615)
This was referenced Nov 10, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stacked on #1392 (and so #1391): review only the last 3 commits.
What and why
Two ways #1391's GPU memory guard misread the residency set, both found running PRAGMATA (
0400C76024710000) on an 8 GB Mac:currentAllocatedSizecounts every no-copy buffer whole. Where several lie over the same guest pages (a large pool's lookup chunks and pool-table segments, PRAGMATA (0400C76024710000) on the Mac: working gameplay at ~38 fps, no flicker; mesh-shaded RE Engine plus host fixes that keep GPU faults from wedging macOS #1407), it reads far above what is wired. At PRAGMATA's boot it read 8,134 MB with the set near 3 GB. The guard's wall then refused the residency commits the game's textures needed. The guard now measures the set after its next commit (g_guard_set), which A game that stops submitting no longer piles up retired pool buffers, the likely cause of the freeze after a window switch #1392 already keeps up to date for additions.DM_NVN_GUARD_DEVICE=1brings back the larger of the two.res_addadds before a commit, but not whatres_removetakes out. A load that retires and replaces buffers in one burst looked like growth only: the guard stopped PRAGMATA at 5,555 MB with the committed set never past 4,220 MB.res_removenow takes its size offg_guard_set, saturating at 0.Reference: the guard's entry in
docs/reference/memory.md("GPU memory past Metal's working set freezes the Mac"), Fix paragraph.Checked
GAME=010015100B514000):check_t_res_guard28 checks and thestuckrun 2 checks, 0 failed. New checks: by default a buffer no set holds does not count; withDM_NVN_GUARD_DEVICE=1it does; a pending removal comes off.test_docs.pyOK.regress.py check --games(no other game builds here); iOS.Docs
docs/reference/memory.mdentry is updated, andpython3 dm/tools/docs_symptoms.pywas run🤖 Generated with Claude Code
https://claude.ai/code/session_01DeVTtdCXD7t64Ek6e1py6A