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 <rbradford@meta.com>
This commit is contained in:
Rob Bradford
2026-03-31 04:41:51 -07:00
parent a0bbef3a76
commit 63aeb597ef
5 changed files with 17 additions and 24 deletions

View File

@@ -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<GuestMemoryAtomic<GuestMemoryMmap>>,
epoll_thread: Option<thread::JoinHandle<()>>,
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();
}

View File

@@ -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<GuestMemoryAtomic<GuestMemoryMmap>>,
epoll_thread: Option<thread::JoinHandle<()>>,
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();
}

View File

@@ -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<GuestMemoryAtomic<GuestMemoryMmap>>,
epoll_thread: Option<thread::JoinHandle<()>>,
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();
}

View File

@@ -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<Arc<dyn VirtioInterrupt>>,
pub vring_bases: Option<Vec<u64>>,
pub epoll_thread: Option<thread::JoinHandle<()>>,
}
impl VhostUserCommon {

View File

@@ -46,7 +46,6 @@ pub struct Net {
config: VirtioNetConfig,
guest_memory: Option<GuestMemoryAtomic<GuestMemoryMmap>>,
ctrl_queue_epoll_thread: Option<thread::JoinHandle<()>>,
epoll_thread: Option<thread::JoinHandle<()>>,
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();
}