vm-virtio: Pausable macro factorization improvements

By adding an internal layer of abstraction (the hidden VirtioPausable
trait), we can factorize the virtio common code.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
This commit is contained in:
Samuel Ortiz
2020-01-27 18:59:39 +01:00
committed by Sebastien Boeuf
parent c06a827cbb
commit 2cb7ec04a4
3 changed files with 76 additions and 56 deletions
+1 -4
View File
@@ -1011,9 +1011,6 @@ impl<T: 'static + DiskFile + Send> VirtioDevice for Block<T> {
} }
} }
impl<T: 'static + DiskFile + Send> Pausable for Block<T> { virtio_pausable!(Block, T: 'static + DiskFile + Send);
virtio_pausable_inner!();
}
impl<T: 'static + DiskFile + Send> Snapshotable for Block<T> {} impl<T: 'static + DiskFile + Send> Snapshotable for Block<T> {}
impl<T: 'static + DiskFile + Send> Migratable for Block<T> {} impl<T: 'static + DiskFile + Send> Migratable for Block<T> {}
+74 -46
View File
@@ -113,9 +113,10 @@ pub trait DmaRemapping: Send + Sync {
} }
#[macro_export] #[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!( debug!(
"Pausing virtio-{}", "Pausing virtio-{}",
VirtioDeviceType::from(self.device_type()) VirtioDeviceType::from(self.device_type())
@@ -130,7 +131,7 @@ macro_rules! virtio_pausable_inner {
Ok(()) Ok(())
} }
fn resume(&mut self) -> result::Result<(), MigratableError> { fn virtio_resume(&mut self) -> result::Result<(), MigratableError> {
debug!( debug!(
"Resuming virtio-{}", "Resuming virtio-{}",
VirtioDeviceType::from(self.device_type()) 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(()) Ok(())
} }
}; };
} }
#[macro_export] #[macro_export]
macro_rules! virtio_pausable { macro_rules! virtio_pausable_trait {
($name:ident) => { ($type:ident) => {
impl Pausable for $name { trait VirtioPausable {
virtio_pausable_inner!(); 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 { ($type:ident, T: $($bounds:tt)+) => {
virtio_pausable_inner!($ctrl_q, $mq); trait VirtioPausable {
fn virtio_pause(&mut self) -> std::result::Result<(), MigratableError>;
fn virtio_resume(&mut self) -> std::result::Result<(), MigratableError>;
}
impl<T: $($bounds)+ > VirtioPausable for $type<T> {
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<T: $($bounds)+ > Pausable for $type<T> {
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(())
}
} }
}; };
} }
+1 -6
View File
@@ -588,12 +588,7 @@ where
} }
} }
impl<B> Pausable for Vsock<B> virtio_pausable!(Vsock, T: 'static + VsockBackend + Sync);
where
B: VsockBackend + Sync + 'static,
{
virtio_pausable_inner!();
}
impl<B> Snapshotable for Vsock<B> where B: VsockBackend + Sync + 'static {} impl<B> Snapshotable for Vsock<B> where B: VsockBackend + Sync + 'static {}
impl<B> Migratable for Vsock<B> where B: VsockBackend + Sync + 'static {} impl<B> Migratable for Vsock<B> where B: VsockBackend + Sync + 'static {}