mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2026-04-25 07:46:01 +03:00
[PR #3186] [MERGED] buffer_cache: Fix various thread races on data upload and invalidation #3292
Labels
No labels
Bloodborne
bug
contributor wanted
documentation
enhancement
frontend
good first issue
help wanted
linux
pull-request
question
release
verification progress
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
starred/shadPS4#3292
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
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?
📋 Pull Request Information
Original PR: https://github.com/shadps4-emu/shadPS4/pull/3186
Author: @raphaelthegreat
Created: 7/3/2025
Status: ✅ Merged
Merged: 7/3/2025
Merged by: @LNDF
Base:
main← Head:read-races📝 Commits (3)
212e37bbuffer_cache: Fix various thread races on data upload and invalidation70b4b98memory_tracker: Improve locking more on invalidation1273155Merge branch 'main' into read-races📊 Changes
5 files changed (+84 additions, -84 deletions)
View changed files
📝
src/video_core/buffer_cache/buffer_cache.cpp(+26 -54)📝
src/video_core/buffer_cache/buffer_cache.h(+4 -3)📝
src/video_core/buffer_cache/memory_tracker.h(+37 -11)📝
src/video_core/buffer_cache/region_manager.h(+13 -13)📝
src/video_core/page_manager.cpp(+4 -3)📄 Description
With this PR the address space critical log spam with readbacks enabled should be gone.
On x64 in any operating system having pages marked with write-only protection is not allowed and it depends on the OS how its handled. On Linux it appears to silently make the page noaccess, while on windows it throws an error like mentioned.
To avoid this the backend always first drops the write access by syncing CPU data and then marks the area as GPU modified which drops the read access. On page invalidation the opposite order is used. However because these actions are separate, when multiple threads attempt to access the same page together with GPU thread, those protect actions can become interleaved and result in invalid protection state
To resolve this, whenever 2 protect actions are necessary they are fused under a single function call and mutex lock, so page state is always in a known state before each one. I've also fixed another race that could occur during CPU data upload. It could be possible while the memcpy to staging buffer performed in SynchronizeBuffer, that another thread invalidates that page and writes new data. Unless that page is invalidated again that data would not get synced. Now the memcpy is performed inside the ForEachUploadRange function with a mutex lock and protection is moved to be before the memcpy again, so that if another page attempts to write there it will have to wait first
🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.