mirror of
https://github.com/tangerineturtle1/NX2navi.git
synced 2026-11-15 19:19:58 -04:00
Mark a region for the lazy write-back before its pages become inaccessible, so that a read during an arm is not passed to the crash handler.
mem_lazy_arm made a range's pages inaccessible (lazy_protect_locked: the protect, then the back end's clean test) and set the region's lzr mark only after the segment was in the list. lazy_fault returns 0 at once for an unmarked region, without taking frz_lock, so a CPU read in that window found the page inaccessible in access_fault and went to the crash handler as an access violation. A write survived only because thaw_fault waits for frz_lock. Arms come from the completion thread (vk_memory.c vk_gpu_written_back) when a submission's fence completes, which is when the game's own fence wait returns and it reads the results; the window lasts as long as the protect and the clean test, which can take tens of milliseconds while the driver pins memory. The mark is now set before the protect, after the cheap refusals, and put back when the protect or the clean test refuses the arm. A fault from the protect on finds the mark, waits for frz_lock and then finds the segment, or the pages given back. Every store to lzr is made under frz_lock, which the arm holds, so putting it back is exact. Not reproduced in the game before the change. The new tests\lazy_fetch_check.py reproduces it with the real Windows fault handler: a thread reads a page while it is armed and given back 20,000 times (arm_race: an access violation in 5 of 6 runs before the change), and once with a clean test of 100 ms (arm_race_slow: an access violation in every run). Both pass in every run since. wb_lazy_check, heap_lazy_copy_check, freeze_hold_check and mem_growth_check passed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -688,6 +688,12 @@ A change to where the lazy write-back is on by default (`runtime/wb_lazy_choice.
|
||||
`vk_mem_lazy_decide`) passes `python tests\wb_lazy_check.py`, which builds the header alone and checks the choice and
|
||||
its reason by platform, by GPU driver and by what the player set. No game files, no GPU.
|
||||
|
||||
A change to the lazy write-back's arms, faults and releases (`runtime/memory.c` "Lazy write-back") passes
|
||||
`python tests\lazy_fetch_check.py`, which builds memory.c with the Windows fault handler and a fetch that only waits,
|
||||
and runs each scenario as its own process, so an access violation fails it: a thread that reads a range over and over
|
||||
while it is armed and given back again never reaches the crash handler, also when the arm's clean test takes 100 ms.
|
||||
Windows only; no game files, no GPU.
|
||||
|
||||
A change to when the freezing of idle guest regions waits (`runtime/freeze_hold.h`, `runtime/vk_memory.c`
|
||||
`freeze_pass`) passes `python tests\freeze_hold_check.py`, which builds the header alone: the backoff after a slow
|
||||
freeze doubles while slow ones come within the quiet time, fast freezes between them included, stops at its cap and
|
||||
|
||||
Reference in New Issue
Block a user