From 63aeb597ef3c7a24e32d4c7cd2935eacc0e38db3 Mon Sep 17 00:00:00 2001 From: Rob Bradford Date: Tue, 31 Mar 2026 04:41:51 -0700 Subject: [PATCH] virtio-devices: Move epoll_thread to VhostUserCommon This is used by all devices so it can be part of the common state. Moving it simplifies the code and simplifies some future improvements around shutdown for migration. Signed-off-by: Rob Bradford --- virtio-devices/src/vhost_user/blk.rs | 10 ++++------ virtio-devices/src/vhost_user/fs.rs | 10 ++++------ virtio-devices/src/vhost_user/generic_vhost_user.rs | 10 ++++------ virtio-devices/src/vhost_user/mod.rs | 3 ++- virtio-devices/src/vhost_user/net.rs | 8 +++----- 5 files changed, 17 insertions(+), 24 deletions(-) diff --git a/virtio-devices/src/vhost_user/blk.rs b/virtio-devices/src/vhost_user/blk.rs index f6e9a4623..529eb517d 100644 --- a/virtio-devices/src/vhost_user/blk.rs +++ b/virtio-devices/src/vhost_user/blk.rs @@ -3,7 +3,7 @@ use std::sync::atomic::AtomicBool; use std::sync::{Arc, Barrier, Mutex}; -use std::{mem, result, thread}; +use std::{mem, result}; use block::VirtioBlockConfig; use event_monitor::event; @@ -43,7 +43,6 @@ pub struct Blk { id: String, config: VirtioBlockConfig, guest_memory: Option>, - epoll_thread: Option>, seccomp_action: SeccompAction, exit_evt: EventFd, iommu: bool, @@ -190,7 +189,6 @@ impl Blk { id, config, guest_memory: None, - epoll_thread: None, seccomp_action, exit_evt, iommu, @@ -210,7 +208,7 @@ impl Drop for Blk { error!("failed to kill vhost-user-blk: {e:?}"); } self.vu_common.virtio_common.wait_for_epoll_threads(); - if let Some(thread) = self.epoll_thread.take() + if let Some(thread) = self.vu_common.epoll_thread.take() && let Err(e) = thread.join() { error!("Error joining thread: {e:?}"); @@ -311,7 +309,7 @@ impl VirtioDevice for Blk { &self.exit_evt, move || handler.run(&paused, paused_sync.as_ref().unwrap()), )?; - self.epoll_thread = Some(epoll_threads.remove(0)); + self.vu_common.epoll_thread = Some(epoll_threads.remove(0)); Ok(()) } @@ -361,7 +359,7 @@ impl Pausable for Blk { fn resume(&mut self) -> result::Result<(), MigratableError> { self.vu_common.virtio_common.resume()?; - if let Some(epoll_thread) = &self.epoll_thread { + if let Some(epoll_thread) = &self.vu_common.epoll_thread { epoll_thread.thread().unpark(); } diff --git a/virtio-devices/src/vhost_user/fs.rs b/virtio-devices/src/vhost_user/fs.rs index 3f982ff29..71859365e 100644 --- a/virtio-devices/src/vhost_user/fs.rs +++ b/virtio-devices/src/vhost_user/fs.rs @@ -1,9 +1,9 @@ // Copyright 2019 Intel Corporation. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 +use std::result; use std::sync::atomic::AtomicBool; use std::sync::{Arc, Barrier, Mutex}; -use std::{result, thread}; use event_monitor::event; use log::{error, info}; @@ -67,7 +67,6 @@ pub struct Fs { cache: Option<(VirtioSharedMemoryList, MmapRegion)>, seccomp_action: SeccompAction, guest_memory: Option>, - epoll_thread: Option>, exit_evt: EventFd, iommu: bool, } @@ -200,7 +199,6 @@ impl Fs { cache, seccomp_action, guest_memory: None, - epoll_thread: None, exit_evt, iommu, }) @@ -218,7 +216,7 @@ impl Drop for Fs { let _ = kill_evt.write(1); } self.vu_common.virtio_common.wait_for_epoll_threads(); - if let Some(thread) = self.epoll_thread.take() + if let Some(thread) = self.vu_common.epoll_thread.take() && let Err(e) = thread.join() { error!("Error joining thread: {e:?}"); @@ -290,7 +288,7 @@ impl VirtioDevice for Fs { &self.exit_evt, move || handler.run(&paused, paused_sync.as_ref().unwrap()), )?; - self.epoll_thread = Some(epoll_threads.remove(0)); + self.vu_common.epoll_thread = Some(epoll_threads.remove(0)); event!("virtio-device", "activated", "id", &self.id); Ok(()) @@ -371,7 +369,7 @@ impl Pausable for Fs { fn resume(&mut self) -> result::Result<(), MigratableError> { self.vu_common.virtio_common.resume()?; - if let Some(epoll_thread) = &self.epoll_thread { + if let Some(epoll_thread) = &self.vu_common.epoll_thread { epoll_thread.thread().unpark(); } diff --git a/virtio-devices/src/vhost_user/generic_vhost_user.rs b/virtio-devices/src/vhost_user/generic_vhost_user.rs index 0554973f8..83f3fe465 100644 --- a/virtio-devices/src/vhost_user/generic_vhost_user.rs +++ b/virtio-devices/src/vhost_user/generic_vhost_user.rs @@ -2,9 +2,9 @@ // Copyright 2025 Demi Marie Obenour. // SPDX-License-Identifier: Apache-2.0 +use std::result; use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::{Arc, Barrier, Mutex}; -use std::{result, thread}; use event_monitor::event; use log::{error, info, warn}; @@ -41,7 +41,6 @@ pub struct GenericVhostUser { cache: Option<(VirtioSharedMemoryList, MmapRegion)>, seccomp_action: SeccompAction, guest_memory: Option>, - epoll_thread: Option>, exit_evt: EventFd, iommu: bool, cfg_warning: AtomicBool, @@ -159,7 +158,6 @@ since the backend only supports {backend_num_queues}\n", cache, seccomp_action, guest_memory: None, - epoll_thread: None, exit_evt, iommu, cfg_warning: AtomicBool::new(false), @@ -193,7 +191,7 @@ impl Drop for GenericVhostUser { let _ = kill_evt.write(1); } self.vu_common.virtio_common.wait_for_epoll_threads(); - if let Some(thread) = self.epoll_thread.take() + if let Some(thread) = self.vu_common.epoll_thread.take() && let Err(e) = thread.join() { error!("Error joining thread: {e:?}"); @@ -313,7 +311,7 @@ impl VirtioDevice for GenericVhostUser { &self.exit_evt, move || handler.run(&paused, paused_sync.as_ref().unwrap()), )?; - self.epoll_thread = Some(epoll_threads.remove(0)); + self.vu_common.epoll_thread = Some(epoll_threads.remove(0)); event!("virtio-device", "activated", "id", &self.id); Ok(()) @@ -394,7 +392,7 @@ impl Pausable for GenericVhostUser { fn resume(&mut self) -> result::Result<(), MigratableError> { self.vu_common.virtio_common.resume()?; - if let Some(epoll_thread) = &self.epoll_thread { + if let Some(epoll_thread) = &self.vu_common.epoll_thread { epoll_thread.thread().unpark(); } diff --git a/virtio-devices/src/vhost_user/mod.rs b/virtio-devices/src/vhost_user/mod.rs index a80c5aa23..3ececc663 100644 --- a/virtio-devices/src/vhost_user/mod.rs +++ b/virtio-devices/src/vhost_user/mod.rs @@ -1,11 +1,11 @@ // Copyright 2019 Intel Corporation. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -use std::io; use std::ops::Deref; use std::os::unix::io::AsRawFd; use std::sync::atomic::AtomicBool; use std::sync::{Arc, Barrier, Mutex}; +use std::{io, thread}; use anyhow::anyhow; use log::error; @@ -345,6 +345,7 @@ pub struct VhostUserCommon { pub server: bool, pub interrupt_cb: Option>, pub vring_bases: Option>, + pub epoll_thread: Option>, } impl VhostUserCommon { diff --git a/virtio-devices/src/vhost_user/net.rs b/virtio-devices/src/vhost_user/net.rs index a270ed541..7cd4e4207 100644 --- a/virtio-devices/src/vhost_user/net.rs +++ b/virtio-devices/src/vhost_user/net.rs @@ -46,7 +46,6 @@ pub struct Net { config: VirtioNetConfig, guest_memory: Option>, ctrl_queue_epoll_thread: Option>, - epoll_thread: Option>, seccomp_action: SeccompAction, exit_evt: EventFd, iommu: bool, @@ -219,7 +218,6 @@ impl Net { config, guest_memory: None, ctrl_queue_epoll_thread: None, - epoll_thread: None, seccomp_action, exit_evt, iommu, @@ -241,7 +239,7 @@ impl Drop for Net { self.vu_common.virtio_common.wait_for_epoll_threads(); - if let Some(thread) = self.epoll_thread.take() + if let Some(thread) = self.vu_common.epoll_thread.take() && let Err(e) = thread.join() { error!("Error joining thread: {e:?}"); @@ -374,7 +372,7 @@ impl VirtioDevice for Net { &self.exit_evt, move || handler.run(&paused, paused_sync.as_ref().unwrap()), )?; - self.epoll_thread = Some(epoll_threads.remove(0)); + self.vu_common.epoll_thread = Some(epoll_threads.remove(0)); Ok(()) } @@ -424,7 +422,7 @@ impl Pausable for Net { fn resume(&mut self) -> result::Result<(), MigratableError> { self.vu_common.virtio_common.resume()?; - if let Some(epoll_thread) = &self.epoll_thread { + if let Some(epoll_thread) = &self.vu_common.epoll_thread { epoll_thread.thread().unpark(); }