From 1363891df6f5f68e5d3a4dffcc4731ede0d974de Mon Sep 17 00:00:00 2001 From: Bo Chen Date: Wed, 13 Mar 2024 15:14:35 -0700 Subject: [PATCH] vmm: Avoid deadlock from waiting on paused device worker threads A deadlock can happen from the destination VM of live upgrade or migration due to waiting on paused device worker threads. For example, when a serialization error happens after the `DeviceManager` struct is restored (where all virtio device worker threads are spawned but in paused/parked state), a deadlock will happen from `DeviceManager::drop()`, as it blocks for waiting worker threads to join. This patch ensures that we wake up all device (mostly virtio) worker threads before we block for them to join. Signed-off-by: Bo Chen --- vmm/src/device_manager.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/vmm/src/device_manager.rs b/vmm/src/device_manager.rs index 6f6e45c74..d8c57847a 100644 --- a/vmm/src/device_manager.rs +++ b/vmm/src/device_manager.rs @@ -4977,6 +4977,12 @@ impl BusDevice for DeviceManager { impl Drop for DeviceManager { fn drop(&mut self) { + // Wake up the DeviceManager threads (mainly virtio device workers), + // to avoid deadlock on waiting for paused/parked worker threads. + if let Err(e) = self.resume() { + error!("Error resuming DeviceManager: {:?}", e); + } + for handle in self.virtio_devices.drain(..) { handle.virtio_device.lock().unwrap().shutdown(); }