From e5dbf5242e25eda3310787fd698ba64bd7534b96 Mon Sep 17 00:00:00 2001 From: Vincent Thomas Date: Thu, 9 Apr 2026 14:46:08 +0000 Subject: [PATCH] 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 --- virtio-devices/src/device.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/virtio-devices/src/device.rs b/virtio-devices/src/device.rs index d1b925799..3e6b30e79 100644 --- a/virtio-devices/src/device.rs +++ b/virtio-devices/src/device.rs @@ -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)