mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-04-22 04:25:19 +00:00
vk: Fix potential MTRSX deadlock in case of a race condition
This commit is contained in:
parent
f3877d11e8
commit
2ae83782e1
3 changed files with 20 additions and 7 deletions
|
@ -734,7 +734,7 @@ bool VKGSRender::on_access_violation(u32 address, bool is_writing)
|
|||
if (g_fxo->get<rsx::dma_manager>()->is_current_thread())
|
||||
{
|
||||
// The offloader thread cannot handle flush requests
|
||||
verify(HERE), m_queue_status.load() == flush_queue_state::ok;
|
||||
verify(HERE), !(m_queue_status & flush_queue_state::deadlock);
|
||||
|
||||
m_offloader_fault_range = g_fxo->get<rsx::dma_manager>()->get_fault_range(is_writing);
|
||||
m_offloader_fault_cause = (is_writing) ? rsx::invalidation_cause::write : rsx::invalidation_cause::read;
|
||||
|
@ -2273,13 +2273,15 @@ void VKGSRender::do_local_task(rsx::FIFO_state state)
|
|||
// NOTE: This may cause graphics corruption due to unsynchronized modification
|
||||
on_invalidate_memory_range(m_offloader_fault_range, m_offloader_fault_cause);
|
||||
m_queue_status.clear(flush_queue_state::deadlock);
|
||||
|
||||
// Abort all other operations, this is likely coming from offloader::sync() and we need to unwind the call stack.
|
||||
// If flush_command_queue is executed at this point, recursion will cause a deadlock to occur.
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_flush_requests.pending())
|
||||
if (m_queue_status & flush_queue_state::flushing)
|
||||
{
|
||||
// Abort recursive CB submit requests.
|
||||
// When flushing flag is already set, only deadlock events may be processed.
|
||||
return;
|
||||
}
|
||||
else if (m_flush_requests.pending())
|
||||
{
|
||||
if (m_flush_queue_mutex.try_lock())
|
||||
{
|
||||
|
@ -2676,6 +2678,8 @@ void VKGSRender::init_buffers(rsx::framebuffer_creation_context context, bool)
|
|||
|
||||
void VKGSRender::close_and_submit_command_buffer(vk::fence* pFence, VkSemaphore wait_semaphore, VkSemaphore signal_semaphore, VkPipelineStageFlags pipeline_stage_flags)
|
||||
{
|
||||
verify("Recursive calls to submit the current commandbuffer will cause a deadlock" HERE), !m_queue_status.test_and_set(flush_queue_state::flushing);
|
||||
|
||||
// Workaround for deadlock occuring during RSX offloader fault
|
||||
// TODO: Restructure command submission infrastructure to avoid this condition
|
||||
const bool sync_success = g_fxo->get<rsx::dma_manager>()->sync();
|
||||
|
@ -2747,6 +2751,8 @@ void VKGSRender::close_and_submit_command_buffer(vk::fence* pFence, VkSemaphore
|
|||
{
|
||||
verify(HERE), m_current_command_buffer->submit_fence->flushed;
|
||||
}
|
||||
|
||||
m_queue_status.clear(flush_queue_state::flushing);
|
||||
}
|
||||
|
||||
void VKGSRender::open_command_buffer()
|
||||
|
|
|
@ -342,7 +342,8 @@ private:
|
|||
enum flush_queue_state : u32
|
||||
{
|
||||
ok = 0,
|
||||
deadlock = 1
|
||||
flushing = 1,
|
||||
deadlock = 2
|
||||
};
|
||||
|
||||
private:
|
||||
|
|
|
@ -848,6 +848,12 @@ namespace rsx
|
|||
m_data.fetch_or(static_cast<bitmask_type>(mask));
|
||||
}
|
||||
|
||||
bool test_and_set(T mask)
|
||||
{
|
||||
const auto old = m_data.fetch_or(static_cast<bitmask_type>(mask));
|
||||
return (old & static_cast<bitmask_type>(mask)) != 0;
|
||||
}
|
||||
|
||||
auto clear(T mask)
|
||||
{
|
||||
bitmask_type clear_mask = ~(static_cast<bitmask_type>(mask));
|
||||
|
|
Loading…
Add table
Reference in a new issue