Use a shared mutex for GPU VMM to avoid deadlocks

Two reads need to be able to occur simultanously or deadlocks ccan occur (e.g read traps to wait on GPU but GPU needs to read).
This commit is contained in:
Billy Laws 2022-12-31 22:56:47 +00:00
parent 28b2a7a8a1
commit 12d80fe6c2
2 changed files with 7 additions and 7 deletions

View File

@ -55,7 +55,7 @@ namespace skyline {
}
};
SpinLock blockMutex;
std::shared_mutex blockMutex;
std::vector<Block> blocks{Block{}};
/**
@ -141,7 +141,7 @@ namespace skyline {
* @return A span of the mapped region and the offset of the input VA in the region
*/
__attribute__((always_inline)) std::pair<span<u8>, VaType> LookupBlock(VaType virt, std::function<void(span<u8>)> cpuAccessCallback = {}) {
std::scoped_lock lock{this->blockMutex};
std::shared_lock lock{this->blockMutex};
return LookupBlockLocked(virt, cpuAccessCallback);
}
@ -149,7 +149,7 @@ namespace skyline {
* @brief Translates a region in the VA space to a corresponding set of regions in the PA space
*/
TranslatedAddressRange TranslateRange(VaType virt, VaType size, std::function<void(span<u8>)> cpuAccessCallback = {}) {
std::scoped_lock lock{this->blockMutex};
std::shared_lock lock{this->blockMutex};
// Fast path for when the range is mapped in a single block
auto [blockSpan, rangeOffset]{LookupBlockLocked(virt, cpuAccessCallback)};
@ -188,7 +188,7 @@ namespace skyline {
span<u8> ReadTill(Container& destination, VaType virt, Function function, std::function<void(span<u8>)> cpuAccessCallback = {}) {
//TRACE_EVENT("containers", "FlatMemoryManager::ReadTill");
std::scoped_lock lock(this->blockMutex);
std::shared_lock lock(this->blockMutex);
auto successor{std::upper_bound(this->blocks.begin(), this->blocks.end(), virt, [](auto virt, const auto &block) {
return virt < block.virt;

View File

@ -287,7 +287,7 @@ namespace skyline {
MM_MEMBER(void)::Read(u8 *destination, VaType virt, VaType size, std::function<void(span<u8>)> cpuAccessCallback) {
TRACE_EVENT("containers", "FlatMemoryManager::Read");
std::scoped_lock lock(this->blockMutex);
std::shared_lock lock(this->blockMutex);
auto successor{std::upper_bound(this->blocks.begin(), this->blocks.end(), virt, [] (auto virt, const auto &block) {
return virt < block.virt;
@ -327,7 +327,7 @@ namespace skyline {
MM_MEMBER(void)::Write(VaType virt, u8 *source, VaType size, std::function<void(span<u8>)> cpuAccessCallback) {
TRACE_EVENT("containers", "FlatMemoryManager::Write");
std::scoped_lock lock(this->blockMutex);
std::shared_lock lock(this->blockMutex);
VaType virtEnd{virt + size};
@ -367,7 +367,7 @@ namespace skyline {
MM_MEMBER(void)::Copy(VaType dst, VaType src, VaType size, std::function<void(span<u8>)> cpuAccessCallback) {
TRACE_EVENT("containers", "FlatMemoryManager::Copy");
std::scoped_lock lock(this->blockMutex);
std::shared_lock lock(this->blockMutex);
VaType srcEnd{src + size};
VaType dstEnd{dst + size};