diff --git a/vm-virtio/src/block.rs b/vm-virtio/src/block.rs index 3a00dd72b..50b808223 100755 --- a/vm-virtio/src/block.rs +++ b/vm-virtio/src/block.rs @@ -1011,9 +1011,6 @@ impl VirtioDevice for Block { } } -impl Pausable for Block { - virtio_pausable_inner!(); -} - +virtio_pausable!(Block, T: 'static + DiskFile + Send); impl Snapshotable for Block {} impl Migratable for Block {} diff --git a/vm-virtio/src/device.rs b/vm-virtio/src/device.rs index c7bef1808..f0baa9a8b 100644 --- a/vm-virtio/src/device.rs +++ b/vm-virtio/src/device.rs @@ -113,9 +113,10 @@ pub trait DmaRemapping: Send + Sync { } #[macro_export] -macro_rules! virtio_pausable_inner { +macro_rules! virtio_pausable_trait_inner { () => { - fn pause(&mut self) -> result::Result<(), MigratableError> { + // This is the common Pausable trait implementation for virtio. + fn virtio_pause(&mut self) -> result::Result<(), MigratableError> { debug!( "Pausing virtio-{}", VirtioDeviceType::from(self.device_type()) @@ -130,7 +131,7 @@ macro_rules! virtio_pausable_inner { Ok(()) } - fn resume(&mut self) -> result::Result<(), MigratableError> { + fn virtio_resume(&mut self) -> result::Result<(), MigratableError> { debug!( "Resuming virtio-{}", VirtioDeviceType::from(self.device_type()) @@ -142,57 +143,84 @@ macro_rules! virtio_pausable_inner { } } - Ok(()) - } - }; - ($ctrl_q:expr, $mq:expr) => { - fn pause(&mut self) -> result::Result<(), MigratableError> { - debug!( - "Pausing virtio-{}", - VirtioDeviceType::from(self.device_type()) - ); - self.paused.store(true, Ordering::SeqCst); - if let Some(pause_evt) = &self.pause_evt { - pause_evt - .write(1) - .map_err(|e| MigratableError::Pause(e.into()))?; - } - - Ok(()) - } - - fn resume(&mut self) -> result::Result<(), MigratableError> { - debug!( - "Resuming virtio-{}", - VirtioDeviceType::from(self.device_type()) - ); - self.paused.store(false, Ordering::SeqCst); - - if let Some(epoll_threads) = &self.epoll_threads { - for i in 0..epoll_threads.len() { - epoll_threads[i].thread().unpark(); - } - } - - if let Some(ctrl_queue_epoll_thread) = &self.ctrl_queue_epoll_thread { - ctrl_queue_epoll_thread.thread().unpark(); - } - Ok(()) } }; } #[macro_export] -macro_rules! virtio_pausable { - ($name:ident) => { - impl Pausable for $name { - virtio_pausable_inner!(); +macro_rules! virtio_pausable_trait { + ($type:ident) => { + trait VirtioPausable { + fn virtio_pause(&mut self) -> std::result::Result<(), MigratableError>; + fn virtio_resume(&mut self) -> std::result::Result<(), MigratableError>; + } + + impl VirtioPausable for $type { + virtio_pausable_trait_inner!(); } }; - ($name:ident, $ctrl_q:expr, $mq:expr) => { - impl Pausable for $name { - virtio_pausable_inner!($ctrl_q, $mq); + + ($type:ident, T: $($bounds:tt)+) => { + trait VirtioPausable { + fn virtio_pause(&mut self) -> std::result::Result<(), MigratableError>; + fn virtio_resume(&mut self) -> std::result::Result<(), MigratableError>; + } + + impl VirtioPausable for $type { + virtio_pausable_trait_inner!(); + } + }; +} + +#[macro_export] +macro_rules! virtio_pausable { + ($type:ident) => { + virtio_pausable_trait!($type); + + impl Pausable for $type { + fn pause(&mut self) -> result::Result<(), MigratableError> { + self.virtio_pause() + } + + fn resume(&mut self) -> result::Result<(), MigratableError> { + self.virtio_resume() + } + } + }; + + // For type bound virtio types + ($type:ident, T: $($bounds:tt)+) => { + virtio_pausable_trait!($type, T: $($bounds)+); + + impl Pausable for $type { + fn pause(&mut self) -> result::Result<(), MigratableError> { + self.virtio_pause() + } + + fn resume(&mut self) -> result::Result<(), MigratableError> { + self.virtio_resume() + } + } + }; + + ($type:ident, $ctrl_q:expr, $mq: expr) => { + virtio_pausable_trait!($type); + + impl Pausable for $type { + fn pause(&mut self) -> result::Result<(), MigratableError> { + self.virtio_pause() + } + + fn resume(&mut self) -> result::Result<(), MigratableError> { + self.virtio_resume()?; + + if let Some(ctrl_queue_epoll_thread) = &self.ctrl_queue_epoll_thread { + ctrl_queue_epoll_thread.thread().unpark(); + } + + Ok(()) + } } }; } diff --git a/vm-virtio/src/vsock/device.rs b/vm-virtio/src/vsock/device.rs index 9c4915448..a84daed3d 100644 --- a/vm-virtio/src/vsock/device.rs +++ b/vm-virtio/src/vsock/device.rs @@ -588,12 +588,7 @@ where } } -impl Pausable for Vsock -where - B: VsockBackend + Sync + 'static, -{ - virtio_pausable_inner!(); -} +virtio_pausable!(Vsock, T: 'static + VsockBackend + Sync); impl Snapshotable for Vsock where B: VsockBackend + Sync + 'static {} impl Migratable for Vsock where B: VsockBackend + Sync + 'static {}