mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2026-08-05 02:19:16 +00:00
virtio-devices: Make pause idempotent to prevent deadlock
Previously, calling pause() when already paused would wait on a barrier for worker threads that were already parked, causing a deadlock. This situation occurs when the VMM thread holds a device mutex while calling an operation that triggers pause(), and a vCPU thread simultaneously needs that same mutex for MMIO access. With slow I/O backends (like RBD/Ceph), the timing window for this race is larger, making the deadlock more likely to occur, see [0]. Make pause() idempotent by checking the paused state atomically and returning early if already paused, avoiding the barrier wait. [0] https://github.com/cloud-hypervisor/cloud-hypervisor/pull/7948#discussion_r305052509 Signed-off-by: Vincent Thomas <vincent@v-thomas.com>
This commit is contained in:
committed by
Rob Bradford
parent
67cf328a9e
commit
e5dbf5242e
@@ -340,7 +340,13 @@ impl Pausable for VirtioCommon {
|
||||
"Pausing virtio-{}",
|
||||
VirtioDeviceType::from(self.device_type)
|
||||
);
|
||||
self.paused.store(true, Ordering::SeqCst);
|
||||
|
||||
// If already paused, return early to avoid deadlock waiting on barrier
|
||||
// for worker threads that are already parked.
|
||||
if self.paused.swap(true, Ordering::SeqCst) {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
if let Some(pause_evt) = &self.pause_evt {
|
||||
pause_evt
|
||||
.write(1)
|
||||
|
||||
Reference in New Issue
Block a user