Fixed a deadlock caused by locking the device's snatchable lock **after** locking the queue's pending writes (#7582)

This commit is contained in:
RedMindZ 2025-04-21 18:08:57 +03:00 committed by GitHub
parent f79cf6ed23
commit f64eae7734
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -476,6 +476,8 @@ impl Queue {
return Ok(());
};
let snatch_guard = self.device.snatchable_lock.read();
// Platform validation requires that the staging buffer always be
// freed, even if an error occurs. All paths from here must call
// `device.pending_writes.consume`.
@ -489,6 +491,7 @@ impl Queue {
};
let result = self.write_staging_buffer_impl(
&snatch_guard,
&mut pending_writes,
&staging_buffer,
buffer,
@ -522,6 +525,7 @@ impl Queue {
let buffer = buffer.get()?;
let snatch_guard = self.device.snatchable_lock.read();
let mut pending_writes = self.pending_writes.lock();
// At this point, we have taken ownership of the staging_buffer from the
@ -531,6 +535,7 @@ impl Queue {
let staging_buffer = staging_buffer.flush();
let result = self.write_staging_buffer_impl(
&snatch_guard,
&mut pending_writes,
&staging_buffer,
buffer,
@ -583,6 +588,7 @@ impl Queue {
fn write_staging_buffer_impl(
&self,
snatch_guard: &SnatchGuard,
pending_writes: &mut PendingWrites,
staging_buffer: &FlushedStagingBuffer,
buffer: Arc<Buffer>,
@ -595,8 +601,7 @@ impl Queue {
.set_single(&buffer, wgt::BufferUses::COPY_DST)
};
let snatch_guard = self.device.snatchable_lock.read();
let dst_raw = buffer.try_raw(&snatch_guard)?;
let dst_raw = buffer.try_raw(snatch_guard)?;
self.same_device_as(buffer.as_ref())?;
@ -614,7 +619,7 @@ impl Queue {
to: wgt::BufferUses::COPY_SRC,
},
})
.chain(transition.map(|pending| pending.into_hal(&buffer, &snatch_guard)))
.chain(transition.map(|pending| pending.into_hal(&buffer, snatch_guard)))
.collect::<Vec<_>>();
let encoder = pending_writes.activate();
unsafe {