diff options
author | Chuanxiao Dong <chuanxiao.dong@intel.corp-partner.google.com> | 2020-01-13 10:36:59 +0800 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2020-02-06 14:34:57 +0000 |
commit | c65a406abd9d846dfffa9969be6af4e4de97b213 (patch) | |
tree | 193d723a9842d480dc0761f702fc72f2e37fe43e | |
parent | fab42c86ed2aa0ead9c66efdea7adf51975258fb (diff) | |
download | crosvm-c65a406abd9d846dfffa9969be6af4e4de97b213.tar crosvm-c65a406abd9d846dfffa9969be6af4e4de97b213.tar.gz crosvm-c65a406abd9d846dfffa9969be6af4e4de97b213.tar.bz2 crosvm-c65a406abd9d846dfffa9969be6af4e4de97b213.tar.lz crosvm-c65a406abd9d846dfffa9969be6af4e4de97b213.tar.xz crosvm-c65a406abd9d846dfffa9969be6af4e4de97b213.tar.zst crosvm-c65a406abd9d846dfffa9969be6af4e4de97b213.zip |
vhost-net: implement the reset method
Vhost-net reset method can stop the activate thread and let it to return the ownership of eventfds and tap back to the device, so that it is possible to be activated again. BUG=None TEST=launch Crosvm guest with vhost-net. It works fine with iperf test. TEST=cargo test -p devices Change-Id: I8f3cb6939595b4dffa0e95bcffbf9fcc8fcf71ba Signed-off-by: Chuanxiao Dong <chuanxiao.dong@intel.corp-partner.google.com> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/2009665 Reviewed-by: Daniel Verkamp <dverkamp@chromium.org> Tested-by: kokoro <noreply+kokoro@google.com>
-rw-r--r-- | devices/src/virtio/vhost/net.rs | 29 | ||||
-rw-r--r-- | devices/src/virtio/vhost/worker.rs | 11 |
2 files changed, 35 insertions, 5 deletions
diff --git a/devices/src/virtio/vhost/net.rs b/devices/src/virtio/vhost/net.rs index e9dcf14..ff72970 100644 --- a/devices/src/virtio/vhost/net.rs +++ b/devices/src/virtio/vhost/net.rs @@ -25,7 +25,7 @@ const QUEUE_SIZES: &[u16] = &[QUEUE_SIZE; NUM_QUEUES]; pub struct Net<T: TapT, U: VhostNetT<T>> { workers_kill_evt: Option<EventFd>, kill_evt: EventFd, - worker_thread: Option<thread::JoinHandle<()>>, + worker_thread: Option<thread::JoinHandle<(Worker<U>, T)>>, tap: Option<T>, vhost_net_handle: Option<U>, vhost_interrupt: Option<Vec<EventFd>>, @@ -141,6 +141,7 @@ where if let Some(workers_kill_evt) = &self.workers_kill_evt { keep_fds.push(workers_kill_evt.as_raw_fd()); } + keep_fds.push(self.kill_evt.as_raw_fd()); keep_fds } @@ -220,6 +221,7 @@ where if let Err(e) = result { error!("net worker thread exited with error: {}", e); } + (worker, tap) }); match worker_result { @@ -248,6 +250,31 @@ where } } } + + fn reset(&mut self) -> bool { + // Only kill the child if it claimed its eventfd. + if self.workers_kill_evt.is_none() && self.kill_evt.write(1).is_err() { + error!("{}: failed to notify the kill event", self.debug_label()); + return false; + } + + if let Some(worker_thread) = self.worker_thread.take() { + match worker_thread.join() { + Err(_) => { + error!("{}: failed to get back resources", self.debug_label()); + return false; + } + Ok((worker, tap)) => { + self.vhost_net_handle = Some(worker.vhost_handle); + self.tap = Some(tap); + self.vhost_interrupt = Some(worker.vhost_interrupt); + self.workers_kill_evt = Some(worker.kill_evt); + return true; + } + } + } + false + } } #[cfg(test)] diff --git a/devices/src/virtio/vhost/worker.rs b/devices/src/virtio/vhost/worker.rs index 630edaa..1eff01f 100644 --- a/devices/src/virtio/vhost/worker.rs +++ b/devices/src/virtio/vhost/worker.rs @@ -17,10 +17,10 @@ use crate::virtio::{Interrupt, Queue}; pub struct Worker<T: Vhost> { interrupt: Interrupt, queues: Vec<Queue>, - vhost_handle: T, - vhost_interrupt: Vec<EventFd>, + pub vhost_handle: T, + pub vhost_interrupt: Vec<EventFd>, acked_features: u64, - kill_evt: EventFd, + pub kill_evt: EventFd, } impl<T: Vhost> Worker<T> { @@ -130,7 +130,10 @@ impl<T: Vhost> Worker<T> { Token::InterruptResample => { self.interrupt.interrupt_resample(); } - Token::Kill => break 'poll, + Token::Kill => { + let _ = self.kill_evt.read(); + break 'poll; + } } } } |