From a0bbef3a761bd0824c447d06d02b79dff4ab534c Mon Sep 17 00:00:00 2001 From: Rob Bradford Date: Tue, 31 Mar 2026 04:31:35 -0700 Subject: [PATCH] virtio-devices: Embed VirtioCommon in VhostUserCommon Since vhost-user devices are always virtio devices it makes sense to structure this struct inside the VhostUserCommon struct. This then also makes some of the methods on VhostUserCommon cleaner since they can now act directly on the common virtio bits (e.g. for kill_evt) Signed-off-by: Rob Bradford --- virtio-devices/src/vhost_user/blk.rs | 62 +++++++------- virtio-devices/src/vhost_user/fs.rs | 62 +++++++------- .../src/vhost_user/generic_vhost_user.rs | 62 +++++++------- virtio-devices/src/vhost_user/mod.rs | 15 ++-- virtio-devices/src/vhost_user/net.rs | 83 ++++++++++--------- 5 files changed, 145 insertions(+), 139 deletions(-) diff --git a/virtio-devices/src/vhost_user/blk.rs b/virtio-devices/src/vhost_user/blk.rs index 203012b8e..f6e9a4623 100644 --- a/virtio-devices/src/vhost_user/blk.rs +++ b/virtio-devices/src/vhost_user/blk.rs @@ -39,7 +39,6 @@ struct BackendReqHandler {} impl VhostUserFrontendReqHandler for BackendReqHandler {} pub struct Blk { - common: VirtioCommon, vu_common: VhostUserCommon, id: String, config: VirtioBlockConfig, @@ -170,17 +169,17 @@ impl Blk { }; Ok(Blk { - common: VirtioCommon { - device_type: VirtioDeviceType::Block as u32, - queue_sizes: vec![vu_cfg.queue_size; num_queues], - avail_features, - acked_features, - paused_sync: Some(Arc::new(Barrier::new(2))), - min_queues: DEFAULT_QUEUE_NUMBER as u16, - paused: Arc::new(AtomicBool::new(paused)), - ..Default::default() - }, vu_common: VhostUserCommon { + virtio_common: VirtioCommon { + device_type: VirtioDeviceType::Block as u32, + queue_sizes: vec![vu_cfg.queue_size; num_queues], + avail_features, + acked_features, + paused_sync: Some(Arc::new(Barrier::new(2))), + min_queues: DEFAULT_QUEUE_NUMBER as u16, + paused: Arc::new(AtomicBool::new(paused)), + ..Default::default() + }, vu: Some(Arc::new(Mutex::new(vu))), acked_protocol_features, socket_path: vu_cfg.socket, @@ -199,18 +198,18 @@ impl Blk { } fn state(&self) -> std::result::Result { - self.vu_common.state(&self.common, self.config) + self.vu_common.state(self.config) } } impl Drop for Blk { fn drop(&mut self) { - if let Some(kill_evt) = self.common.kill_evt.take() + if let Some(kill_evt) = self.vu_common.virtio_common.kill_evt.take() && let Err(e) = kill_evt.write(1) { error!("failed to kill vhost-user-blk: {e:?}"); } - self.common.wait_for_epoll_threads(); + self.vu_common.virtio_common.wait_for_epoll_threads(); if let Some(thread) = self.epoll_thread.take() && let Err(e) = thread.join() { @@ -221,15 +220,15 @@ impl Drop for Blk { impl VirtioDevice for Blk { fn device_type(&self) -> u32 { - self.common.device_type + self.vu_common.virtio_common.device_type } fn queue_max_sizes(&self) -> &[u16] { - &self.common.queue_sizes + &self.vu_common.virtio_common.queue_sizes } fn features(&self) -> u64 { - let mut features = self.common.avail_features; + let mut features = self.vu_common.virtio_common.avail_features; if self.iommu { features |= 1u64 << VIRTIO_F_ACCESS_PLATFORM; } @@ -237,7 +236,7 @@ impl VirtioDevice for Blk { } fn ack_features(&mut self, value: u64) { - self.common.ack_features(value); + self.vu_common.virtio_common.ack_features(value); } fn read_config(&self, offset: u64, data: &mut [u8]) { @@ -278,27 +277,29 @@ impl VirtioDevice for Blk { queues, .. } = context; - self.common.activate(&queues, interrupt_cb.clone())?; + self.vu_common + .virtio_common + .activate(&queues, interrupt_cb.clone())?; self.guest_memory = Some(mem.clone()); let backend_req_handler: Option> = None; // Run a dedicated thread for handling potential reconnections with // the backend. - let (kill_evt, pause_evt) = self.common.dup_eventfds(); + let (kill_evt, pause_evt) = self.vu_common.virtio_common.dup_eventfds(); let mut handler = self.vu_common.activate( mem, &queues, interrupt_cb, - self.common.acked_features, + self.vu_common.virtio_common.acked_features, backend_req_handler, kill_evt, pause_evt, )?; - let paused = self.common.paused.clone(); - let paused_sync = self.common.paused_sync.clone(); + let paused = self.vu_common.virtio_common.paused.clone(); + let paused_sync = self.vu_common.virtio_common.paused_sync.clone(); let mut epoll_threads = Vec::new(); @@ -317,8 +318,8 @@ impl VirtioDevice for Blk { fn reset(&mut self) -> Option> { // We first must resume the virtio thread if it was paused. - if self.common.pause_evt.take().is_some() { - self.common.resume().ok()?; + if self.vu_common.virtio_common.pause_evt.take().is_some() { + self.vu_common.virtio_common.resume().ok()?; } if let Some(vu) = &self.vu_common.vu @@ -328,7 +329,7 @@ impl VirtioDevice for Blk { return None; } - if let Some(kill_evt) = self.common.kill_evt.take() { + if let Some(kill_evt) = self.vu_common.virtio_common.kill_evt.take() { // Ignore the result because there is nothing we can do about it. let _ = kill_evt.write(1); } @@ -336,7 +337,7 @@ impl VirtioDevice for Blk { event!("virtio-device", "reset", "id", &self.id); // Return the interrupt - Some(self.common.interrupt_cb.take().unwrap()) + Some(self.vu_common.virtio_common.interrupt_cb.take().unwrap()) } fn shutdown(&mut self) { @@ -354,11 +355,11 @@ impl VirtioDevice for Blk { impl Pausable for Blk { fn pause(&mut self) -> result::Result<(), MigratableError> { self.vu_common.pause()?; - self.common.pause() + self.vu_common.virtio_common.pause() } fn resume(&mut self) -> result::Result<(), MigratableError> { - self.common.resume()?; + self.vu_common.virtio_common.resume()?; if let Some(epoll_thread) = &self.epoll_thread { epoll_thread.thread().unpark(); @@ -397,7 +398,6 @@ impl Migratable for Blk { } fn complete_migration(&mut self) -> std::result::Result<(), MigratableError> { - self.vu_common - .complete_migration(self.common.kill_evt.take()) + self.vu_common.complete_migration() } } diff --git a/virtio-devices/src/vhost_user/fs.rs b/virtio-devices/src/vhost_user/fs.rs index 1b8edfe6b..3f982ff29 100644 --- a/virtio-devices/src/vhost_user/fs.rs +++ b/virtio-devices/src/vhost_user/fs.rs @@ -59,7 +59,6 @@ impl Default for VirtioFsConfig { unsafe impl ByteValued for VirtioFsConfig {} pub struct Fs { - common: VirtioCommon, vu_common: VhostUserCommon, id: String, config: VirtioFsConfig, @@ -178,17 +177,17 @@ impl Fs { }; Ok(Fs { - common: VirtioCommon { - device_type: VirtioDeviceType::Fs as u32, - avail_features, - acked_features, - queue_sizes: vec![queue_size; num_queues], - paused_sync: Some(Arc::new(Barrier::new(2))), - min_queues: 1, - paused: Arc::new(AtomicBool::new(paused)), - ..Default::default() - }, vu_common: VhostUserCommon { + virtio_common: VirtioCommon { + device_type: VirtioDeviceType::Fs as u32, + avail_features, + acked_features, + queue_sizes: vec![queue_size; num_queues], + paused_sync: Some(Arc::new(Barrier::new(2))), + min_queues: 1, + paused: Arc::new(AtomicBool::new(paused)), + ..Default::default() + }, vu: Some(Arc::new(Mutex::new(vu))), acked_protocol_features, socket_path: path.to_string(), @@ -208,17 +207,17 @@ impl Fs { } fn state(&self) -> std::result::Result { - self.vu_common.state(&self.common, self.config) + self.vu_common.state(self.config) } } impl Drop for Fs { fn drop(&mut self) { - if let Some(kill_evt) = self.common.kill_evt.take() { + if let Some(kill_evt) = self.vu_common.virtio_common.kill_evt.take() { // Ignore the result because there is nothing we can do about it. let _ = kill_evt.write(1); } - self.common.wait_for_epoll_threads(); + self.vu_common.virtio_common.wait_for_epoll_threads(); if let Some(thread) = self.epoll_thread.take() && let Err(e) = thread.join() { @@ -229,15 +228,15 @@ impl Drop for Fs { impl VirtioDevice for Fs { fn device_type(&self) -> u32 { - self.common.device_type + self.vu_common.virtio_common.device_type } fn queue_max_sizes(&self) -> &[u16] { - &self.common.queue_sizes + &self.vu_common.virtio_common.queue_sizes } fn features(&self) -> u64 { - let mut features = self.common.avail_features; + let mut features = self.vu_common.virtio_common.avail_features; if self.iommu { features |= 1u64 << VIRTIO_F_ACCESS_PLATFORM; } @@ -245,7 +244,7 @@ impl VirtioDevice for Fs { } fn ack_features(&mut self, value: u64) { - self.common.ack_features(value); + self.vu_common.virtio_common.ack_features(value); } fn read_config(&self, offset: u64, data: &mut [u8]) { @@ -259,26 +258,28 @@ impl VirtioDevice for Fs { queues, .. } = context; - self.common.activate(&queues, interrupt_cb.clone())?; + self.vu_common + .virtio_common + .activate(&queues, interrupt_cb.clone())?; self.guest_memory = Some(mem.clone()); let backend_req_handler: Option> = None; // Run a dedicated thread for handling potential reconnections with // the backend. - let (kill_evt, pause_evt) = self.common.dup_eventfds(); + let (kill_evt, pause_evt) = self.vu_common.virtio_common.dup_eventfds(); let mut handler = self.vu_common.activate( mem, &queues, interrupt_cb, - self.common.acked_features, + self.vu_common.virtio_common.acked_features, backend_req_handler, kill_evt, pause_evt, )?; - let paused = self.common.paused.clone(); - let paused_sync = self.common.paused_sync.clone(); + let paused = self.vu_common.virtio_common.paused.clone(); + let paused_sync = self.vu_common.virtio_common.paused_sync.clone(); let mut epoll_threads = Vec::new(); spawn_virtio_thread( @@ -297,8 +298,8 @@ impl VirtioDevice for Fs { fn reset(&mut self) -> Option> { // We first must resume the virtio thread if it was paused. - if self.common.pause_evt.take().is_some() { - self.common.resume().ok()?; + if self.vu_common.virtio_common.pause_evt.take().is_some() { + self.vu_common.virtio_common.resume().ok()?; } if let Some(vu) = &self.vu_common.vu @@ -308,7 +309,7 @@ impl VirtioDevice for Fs { return None; } - if let Some(kill_evt) = self.common.kill_evt.take() { + if let Some(kill_evt) = self.vu_common.virtio_common.kill_evt.take() { // Ignore the result because there is nothing we can do about it. let _ = kill_evt.write(1); } @@ -316,7 +317,7 @@ impl VirtioDevice for Fs { event!("virtio-device", "reset", "id", &self.id); // Return the interrupt - Some(self.common.interrupt_cb.take().unwrap()) + Some(self.vu_common.virtio_common.interrupt_cb.take().unwrap()) } fn shutdown(&mut self) { @@ -364,11 +365,11 @@ impl VirtioDevice for Fs { impl Pausable for Fs { fn pause(&mut self) -> result::Result<(), MigratableError> { self.vu_common.pause()?; - self.common.pause() + self.vu_common.virtio_common.pause() } fn resume(&mut self) -> result::Result<(), MigratableError> { - self.common.resume()?; + self.vu_common.virtio_common.resume()?; if let Some(epoll_thread) = &self.epoll_thread { epoll_thread.thread().unpark(); @@ -407,7 +408,6 @@ impl Migratable for Fs { } fn complete_migration(&mut self) -> std::result::Result<(), MigratableError> { - self.vu_common - .complete_migration(self.common.kill_evt.take()) + self.vu_common.complete_migration() } } diff --git a/virtio-devices/src/vhost_user/generic_vhost_user.rs b/virtio-devices/src/vhost_user/generic_vhost_user.rs index da8fe53a8..0554973f8 100644 --- a/virtio-devices/src/vhost_user/generic_vhost_user.rs +++ b/virtio-devices/src/vhost_user/generic_vhost_user.rs @@ -34,7 +34,6 @@ pub type State = VhostUserState<()>; struct BackendReqHandler {} impl VhostUserFrontendReqHandler for BackendReqHandler {} pub struct GenericVhostUser { - common: VirtioCommon, vu_common: VhostUserCommon, id: String, // Hold ownership of the memory that is allocated for the device @@ -138,17 +137,17 @@ since the backend only supports {backend_num_queues}\n", }; Ok(GenericVhostUser { - common: VirtioCommon { - device_type, - avail_features, - acked_features, - queue_sizes: request_queue_sizes, - paused_sync: Some(Arc::new(Barrier::new(2))), - min_queues: 1, - paused: Arc::new(AtomicBool::new(paused)), - ..Default::default() - }, vu_common: VhostUserCommon { + virtio_common: VirtioCommon { + device_type, + avail_features, + acked_features, + queue_sizes: request_queue_sizes, + paused_sync: Some(Arc::new(Barrier::new(2))), + min_queues: 1, + paused: Arc::new(AtomicBool::new(paused)), + ..Default::default() + }, vu: Some(Arc::new(Mutex::new(vu))), acked_protocol_features, socket_path: path.to_string(), @@ -168,7 +167,7 @@ since the backend only supports {backend_num_queues}\n", } fn state(&self) -> std::result::Result { - self.vu_common.state(&self.common, ()) + self.vu_common.state(()) } #[cold] @@ -189,11 +188,11 @@ space access. Reads will return 0xFF and writes will be ignored." impl Drop for GenericVhostUser { fn drop(&mut self) { - if let Some(kill_evt) = self.common.kill_evt.take() { + if let Some(kill_evt) = self.vu_common.virtio_common.kill_evt.take() { // Ignore the result because there is nothing we can do about it. let _ = kill_evt.write(1); } - self.common.wait_for_epoll_threads(); + self.vu_common.virtio_common.wait_for_epoll_threads(); if let Some(thread) = self.epoll_thread.take() && let Err(e) = thread.join() { @@ -204,15 +203,15 @@ impl Drop for GenericVhostUser { impl VirtioDevice for GenericVhostUser { fn device_type(&self) -> u32 { - self.common.device_type + self.vu_common.virtio_common.device_type } fn queue_max_sizes(&self) -> &[u16] { - &self.common.queue_sizes + &self.vu_common.virtio_common.queue_sizes } fn features(&self) -> u64 { - let mut features = self.common.avail_features; + let mut features = self.vu_common.virtio_common.avail_features; if self.iommu { features |= 1u64 << VIRTIO_F_ACCESS_PLATFORM; } @@ -220,7 +219,7 @@ impl VirtioDevice for GenericVhostUser { } fn ack_features(&mut self, value: u64) { - self.common.ack_features(value); + self.vu_common.virtio_common.ack_features(value); } fn read_config(&self, offset: u64, data: &mut [u8]) { @@ -282,26 +281,28 @@ impl VirtioDevice for GenericVhostUser { queues, .. } = context; - self.common.activate(&queues, interrupt_cb.clone())?; + self.vu_common + .virtio_common + .activate(&queues, interrupt_cb.clone())?; self.guest_memory = Some(mem.clone()); let backend_req_handler: Option> = None; // Run a dedicated thread for handling potential reconnections with // the backend. - let (kill_evt, pause_evt) = self.common.dup_eventfds(); + let (kill_evt, pause_evt) = self.vu_common.virtio_common.dup_eventfds(); let mut handler = self.vu_common.activate( mem, &queues, interrupt_cb, - self.common.acked_features, + self.vu_common.virtio_common.acked_features, backend_req_handler, kill_evt, pause_evt, )?; - let paused = self.common.paused.clone(); - let paused_sync = self.common.paused_sync.clone(); + let paused = self.vu_common.virtio_common.paused.clone(); + let paused_sync = self.vu_common.virtio_common.paused_sync.clone(); let mut epoll_threads = Vec::new(); spawn_virtio_thread( @@ -320,8 +321,8 @@ impl VirtioDevice for GenericVhostUser { fn reset(&mut self) -> Option> { // We first must resume the virtio thread if it was paused. - if self.common.pause_evt.take().is_some() { - self.common.resume().ok()?; + if self.vu_common.virtio_common.pause_evt.take().is_some() { + self.vu_common.virtio_common.resume().ok()?; } if let Some(vu) = &self.vu_common.vu @@ -331,7 +332,7 @@ impl VirtioDevice for GenericVhostUser { return None; } - if let Some(kill_evt) = self.common.kill_evt.take() { + if let Some(kill_evt) = self.vu_common.virtio_common.kill_evt.take() { // Ignore the result because there is nothing we can do about it. let _ = kill_evt.write(1); } @@ -339,7 +340,7 @@ impl VirtioDevice for GenericVhostUser { event!("virtio-device", "reset", "id", &self.id); // Return the interrupt - Some(self.common.interrupt_cb.take().unwrap()) + Some(self.vu_common.virtio_common.interrupt_cb.take().unwrap()) } fn shutdown(&mut self) { @@ -387,11 +388,11 @@ impl VirtioDevice for GenericVhostUser { impl Pausable for GenericVhostUser { fn pause(&mut self) -> result::Result<(), MigratableError> { self.vu_common.pause()?; - self.common.pause() + self.vu_common.virtio_common.pause() } fn resume(&mut self) -> result::Result<(), MigratableError> { - self.common.resume()?; + self.vu_common.virtio_common.resume()?; if let Some(epoll_thread) = &self.epoll_thread { epoll_thread.thread().unpark(); @@ -430,7 +431,6 @@ impl Migratable for GenericVhostUser { } fn complete_migration(&mut self) -> std::result::Result<(), MigratableError> { - self.vu_common - .complete_migration(self.common.kill_evt.take()) + self.vu_common.complete_migration() } } diff --git a/virtio-devices/src/vhost_user/mod.rs b/virtio-devices/src/vhost_user/mod.rs index 86a774737..a80c5aa23 100644 --- a/virtio-devices/src/vhost_user/mod.rs +++ b/virtio-devices/src/vhost_user/mod.rs @@ -29,7 +29,7 @@ use crate::{ ActivateError, EPOLL_HELPER_EVENT_LAST, EpollHelper, EpollHelperError, EpollHelperHandler, GuestMemoryMmap, GuestRegionMmap, VIRTIO_F_IN_ORDER, VIRTIO_F_NOTIFICATION_DATA, VIRTIO_F_ORDER_PLATFORM, VIRTIO_F_RING_EVENT_IDX, VIRTIO_F_RING_INDIRECT_DESC, - VIRTIO_F_VERSION_1, VirtioInterrupt, + VIRTIO_F_VERSION_1, VirtioCommon, VirtioInterrupt, }; pub mod blk; @@ -336,6 +336,7 @@ impl VhostUserState { #[derive(Default)] pub struct VhostUserCommon { + pub virtio_common: VirtioCommon, pub vu: Option>>, pub acked_protocol_features: u64, pub socket_path: String, @@ -485,12 +486,11 @@ impl VhostUserCommon { pub fn state( &self, - common: &crate::VirtioCommon, config: C, ) -> std::result::Result, MigratableError> { let mut state = VhostUserState { - avail_features: common.avail_features, - acked_features: common.acked_features, + avail_features: self.virtio_common.avail_features, + acked_features: self.virtio_common.acked_features, config, acked_protocol_features: self.acked_protocol_features, vu_num_queues: self.vu_num_queues, @@ -586,15 +586,12 @@ impl VhostUserCommon { Ok(()) } - pub fn complete_migration( - &mut self, - kill_evt: Option, - ) -> std::result::Result<(), MigratableError> { + pub fn complete_migration(&mut self) -> std::result::Result<(), MigratableError> { self.migration_started = false; // Make sure the device thread is killed in order to prevent from // reconnections to the socket. - if let Some(kill_evt) = kill_evt { + if let Some(kill_evt) = self.virtio_common.kill_evt.take() { kill_evt.write(1).map_err(|e| { MigratableError::CompleteMigration(anyhow!( "Error killing vhost-user thread: {e:?}" diff --git a/virtio-devices/src/vhost_user/net.rs b/virtio-devices/src/vhost_user/net.rs index d05626901..a270ed541 100644 --- a/virtio-devices/src/vhost_user/net.rs +++ b/virtio-devices/src/vhost_user/net.rs @@ -41,7 +41,6 @@ struct BackendReqHandler {} impl VhostUserFrontendReqHandler for BackendReqHandler {} pub struct Net { - common: VirtioCommon, vu_common: VhostUserCommon, id: String, config: VirtioNetConfig, @@ -198,17 +197,17 @@ impl Net { Ok(Net { id, - common: VirtioCommon { - device_type: VirtioDeviceType::Net as u32, - queue_sizes: vec![vu_cfg.queue_size; num_queues], - avail_features, - acked_features, - paused_sync: Some(Arc::new(Barrier::new(2))), - min_queues: DEFAULT_QUEUE_NUMBER as u16, - paused: Arc::new(AtomicBool::new(paused)), - ..Default::default() - }, vu_common: VhostUserCommon { + virtio_common: VirtioCommon { + device_type: VirtioDeviceType::Net as u32, + queue_sizes: vec![vu_cfg.queue_size; num_queues], + avail_features, + acked_features, + paused_sync: Some(Arc::new(Barrier::new(2))), + min_queues: DEFAULT_QUEUE_NUMBER as u16, + paused: Arc::new(AtomicBool::new(paused)), + ..Default::default() + }, vu: Some(Arc::new(Mutex::new(vu))), acked_protocol_features, socket_path: vu_cfg.socket, @@ -228,19 +227,19 @@ impl Net { } fn state(&self) -> std::result::Result { - self.vu_common.state(&self.common, self.config) + self.vu_common.state(self.config) } } impl Drop for Net { fn drop(&mut self) { - if let Some(kill_evt) = self.common.kill_evt.take() + if let Some(kill_evt) = self.vu_common.virtio_common.kill_evt.take() && let Err(e) = kill_evt.write(1) { error!("failed to kill vhost-user-net: {e:?}"); } - self.common.wait_for_epoll_threads(); + self.vu_common.virtio_common.wait_for_epoll_threads(); if let Some(thread) = self.epoll_thread.take() && let Err(e) = thread.join() @@ -258,15 +257,15 @@ impl Drop for Net { impl VirtioDevice for Net { fn device_type(&self) -> u32 { - self.common.device_type + self.vu_common.virtio_common.device_type } fn queue_max_sizes(&self) -> &[u16] { - &self.common.queue_sizes + &self.vu_common.virtio_common.queue_sizes } fn features(&self) -> u64 { - let mut features = self.common.avail_features; + let mut features = self.vu_common.virtio_common.avail_features; if self.iommu { features |= 1u64 << VIRTIO_F_ACCESS_PLATFORM; } @@ -274,7 +273,7 @@ impl VirtioDevice for Net { } fn ack_features(&mut self, value: u64) { - self.common.ack_features(value); + self.vu_common.virtio_common.ack_features(value); } fn read_config(&self, offset: u64, data: &mut [u8]) { @@ -288,18 +287,28 @@ impl VirtioDevice for Net { mut queues, .. } = context; - self.common.activate(&queues, interrupt_cb.clone())?; + self.vu_common + .virtio_common + .activate(&queues, interrupt_cb.clone())?; self.guest_memory = Some(mem.clone()); let num_queues = queues.len(); - let event_idx = self.common.feature_acked(VIRTIO_RING_F_EVENT_IDX.into()); - if self.common.feature_acked(VIRTIO_NET_F_CTRL_VQ.into()) && !num_queues.is_multiple_of(2) { + let event_idx = self + .vu_common + .virtio_common + .feature_acked(VIRTIO_RING_F_EVENT_IDX.into()); + if self + .vu_common + .virtio_common + .feature_acked(VIRTIO_NET_F_CTRL_VQ.into()) + && !num_queues.is_multiple_of(2) + { let ctrl_queue_index = num_queues - 1; let (_, mut ctrl_queue, ctrl_queue_evt) = queues.remove(ctrl_queue_index); ctrl_queue.set_event_idx(event_idx); - let (kill_evt, pause_evt) = self.common.dup_eventfds(); + let (kill_evt, pause_evt) = self.vu_common.virtio_common.dup_eventfds(); let mut ctrl_handler = NetCtrlEpollHandler { mem: mem.clone(), @@ -313,12 +322,12 @@ impl VirtioDevice for Net { queue_index: ctrl_queue_index as u16, }; - let paused = self.common.paused.clone(); + let paused = self.vu_common.virtio_common.paused.clone(); // Let's update the barrier as we need 1 for the control queue // thread + 1 for the common vhost-user thread + 1 for the main // thread signalling the pause. - self.common.paused_sync = Some(Arc::new(Barrier::new(3))); - let paused_sync = self.common.paused_sync.clone(); + self.vu_common.virtio_common.paused_sync = Some(Arc::new(Barrier::new(3))); + let paused_sync = self.vu_common.virtio_common.paused_sync.clone(); let mut epoll_threads = Vec::new(); spawn_virtio_thread( @@ -336,11 +345,12 @@ impl VirtioDevice for Net { // The backend acknowledged features must not contain VIRTIO_NET_F_MAC // since we don't expect the backend to handle it. - let backend_acked_features = self.common.acked_features & !(1 << VIRTIO_NET_F_MAC); + let backend_acked_features = + self.vu_common.virtio_common.acked_features & !(1 << VIRTIO_NET_F_MAC); // Run a dedicated thread for handling potential reconnections with // the backend. - let (kill_evt, pause_evt) = self.common.dup_eventfds(); + let (kill_evt, pause_evt) = self.vu_common.virtio_common.dup_eventfds(); let mut handler = self.vu_common.activate( mem, @@ -352,8 +362,8 @@ impl VirtioDevice for Net { pause_evt, )?; - let paused = self.common.paused.clone(); - let paused_sync = self.common.paused_sync.clone(); + let paused = self.vu_common.virtio_common.paused.clone(); + let paused_sync = self.vu_common.virtio_common.paused_sync.clone(); let mut epoll_threads = Vec::new(); spawn_virtio_thread( @@ -371,8 +381,8 @@ impl VirtioDevice for Net { fn reset(&mut self) -> Option> { // We first must resume the virtio thread if it was paused. - if self.common.pause_evt.take().is_some() { - self.common.resume().ok()?; + if self.vu_common.virtio_common.pause_evt.take().is_some() { + self.vu_common.virtio_common.resume().ok()?; } if let Some(vu) = &self.vu_common.vu @@ -382,7 +392,7 @@ impl VirtioDevice for Net { return None; } - if let Some(kill_evt) = self.common.kill_evt.take() { + if let Some(kill_evt) = self.vu_common.virtio_common.kill_evt.take() { // Ignore the result because there is nothing we can do about it. let _ = kill_evt.write(1); } @@ -390,7 +400,7 @@ impl VirtioDevice for Net { event!("virtio-device", "reset", "id", &self.id); // Return the interrupt - Some(self.common.interrupt_cb.take().unwrap()) + Some(self.vu_common.virtio_common.interrupt_cb.take().unwrap()) } fn shutdown(&mut self) { @@ -408,11 +418,11 @@ impl VirtioDevice for Net { impl Pausable for Net { fn pause(&mut self) -> result::Result<(), MigratableError> { self.vu_common.pause()?; - self.common.pause() + self.vu_common.virtio_common.pause() } fn resume(&mut self) -> result::Result<(), MigratableError> { - self.common.resume()?; + self.vu_common.virtio_common.resume()?; if let Some(epoll_thread) = &self.epoll_thread { epoll_thread.thread().unpark(); @@ -455,7 +465,6 @@ impl Migratable for Net { } fn complete_migration(&mut self) -> std::result::Result<(), MigratableError> { - self.vu_common - .complete_migration(self.common.kill_evt.take()) + self.vu_common.complete_migration() } }