rsx: Avoid acquiring the vm lock; deadlock evasion

- A possible deadlock is still present if rsx is trying to get a super_ptr whilst the vm lock holder is in an access violation
  This patch makes this scenario very unlikely since each block need only be touched once
This commit is contained in:
kd-11 2018-07-27 00:03:55 +03:00 committed by kd-11
parent 741ee9ac41
commit 38191c3013
6 changed files with 52 additions and 16 deletions

View File

@ -1373,6 +1373,24 @@ namespace rsx
for (const auto& range : m_invalidated_memory_ranges)
{
on_invalidate_memory_range(range.first, range.second);
// Clean the main memory super_ptr cache if invalidated
const auto range_end = range.first + range.second;
for (auto It = main_super_memory_block.begin(); It != main_super_memory_block.end();)
{
const auto mem_start = It->first;
const auto mem_end = mem_start + It->second.size();
const bool overlaps = (mem_start < range_end && range.first < mem_end);
if (overlaps)
{
It = main_super_memory_block.erase(It);
}
else
{
It++;
}
}
}
m_invalidated_memory_ranges.clear();

View File

@ -382,7 +382,8 @@ namespace rsx
GcmZcullInfo zculls[limits::zculls_count];
// Super memory map (mapped block with r/w permissions)
std::pair<u32, std::shared_ptr<u8>> super_memory_map;
std::pair<u32, std::shared_ptr<u8>> local_super_memory_block;
std::unordered_map<u32, rsx::weak_ptr> main_super_memory_block;
bool capture_current_frame = false;
void capture_frame(const std::string &name);

View File

@ -3113,9 +3113,6 @@ bool VKGSRender::scaled_image_from_memory(rsx::blit_src_info& src, rsx::blit_dst
//Verify enough memory exists before attempting to handle data transfer
check_heap_status();
//Stop all parallel operations until this is finished
std::lock_guard<shared_mutex> lock(m_secondary_cb_guard);
if (m_texture_cache.blit(src, dst, interpolate, m_rtts, *m_current_command_buffer))
{
m_samplers_dirty.store(true);

View File

@ -354,7 +354,8 @@ namespace rsx
void flush_io(u32 offset = 0, u32 len = 0) const
{
locked_memory_ptr.flush(offset, len);
const auto write_length = len ? len : (cpu_address_range - offset);
locked_memory_ptr.flush(offset, write_length);
}
std::pair<u32, u32> get_confirmed_range() const

View File

@ -80,15 +80,15 @@ namespace rsx
{
verify(HERE), g_current_renderer;
if (!g_current_renderer->super_memory_map.first)
if (!g_current_renderer->local_super_memory_block.first)
{
auto block = vm::get(vm::any, 0xC0000000);
if (block)
{
g_current_renderer->super_memory_map.first = block->used();
g_current_renderer->super_memory_map.second = vm::get_super_ptr<u8>(0xC0000000, g_current_renderer->super_memory_map.first - 1);
g_current_renderer->local_super_memory_block.first = block->used();
g_current_renderer->local_super_memory_block.second = vm::get_super_ptr<u8>(0xC0000000, g_current_renderer->local_super_memory_block.first - 1);
if (!g_current_renderer->super_memory_map.second)
if (!g_current_renderer->local_super_memory_block.second)
{
//Disjoint allocation?
LOG_ERROR(RSX, "Could not initialize contiguous RSX super-memory");
@ -100,18 +100,30 @@ namespace rsx
}
}
if (g_current_renderer->super_memory_map.second)
if (g_current_renderer->local_super_memory_block.second)
{
if (addr >= 0xC0000000 && (addr + len) <= (0xC0000000 + g_current_renderer->super_memory_map.first))
if (addr >= 0xC0000000 && (addr + len) <= (0xC0000000 + g_current_renderer->local_super_memory_block.first))
{
//RSX local
return { g_current_renderer->super_memory_map.second.get() + (addr - 0xC0000000) };
return { g_current_renderer->local_super_memory_block.second.get() + (addr - 0xC0000000) };
}
}
const auto cached = g_current_renderer->main_super_memory_block.find(addr);
if (cached != g_current_renderer->main_super_memory_block.end())
{
const auto& _ptr = cached->second;
if (_ptr.size() >= len)
{
return _ptr;
}
}
if (auto result = vm::get_super_ptr<u8>(addr, len - 1))
{
return { result };
weak_ptr _ptr = { result, len };
auto &ret = g_current_renderer->main_super_memory_block[addr] = std::move(_ptr);
return _ptr;
}
//Probably allocated as split blocks. Try to grab separate chunks
@ -137,7 +149,9 @@ namespace rsx
next = region.first + region.second->size();
if (next >= limit)
{
return { blocks };
weak_ptr _ptr = { blocks };
auto &ret = g_current_renderer->main_super_memory_block[addr] = std::move(_ptr);
return ret;
}
}

View File

@ -60,9 +60,9 @@ namespace rsx
}
}
weak_ptr(std::shared_ptr<u8>& block)
weak_ptr(std::shared_ptr<u8>& block, u32 size)
{
_blocks.push_back({ block, 0 });
_blocks.push_back({ block, size });
_ptr = block.get();
}
@ -195,6 +195,11 @@ namespace rsx
}
}
u32 size() const
{
return contiguous ? _blocks[0].second : (u32)io_cache.size();
}
operator bool() const
{
return (_ptr != nullptr || _blocks.size() > 1);