summary refs log tree commit diff
diff options
context:
space:
mode:
authorChuanxiao Dong <chuanxiao.dong@intel.corp-partner.google.com>2020-01-13 10:23:52 +0800
committerCommit Bot <commit-bot@chromium.org>2020-02-03 09:47:41 +0000
commitbc499ec2780510083f001bef569449808ad55850 (patch)
tree3754d9915bc43a38fe2451ec5a4fe46bed272c9b
parent282115bcdb3842e507357ec131d1c3685551fb1b (diff)
downloadcrosvm-bc499ec2780510083f001bef569449808ad55850.tar
crosvm-bc499ec2780510083f001bef569449808ad55850.tar.gz
crosvm-bc499ec2780510083f001bef569449808ad55850.tar.bz2
crosvm-bc499ec2780510083f001bef569449808ad55850.tar.lz
crosvm-bc499ec2780510083f001bef569449808ad55850.tar.xz
crosvm-bc499ec2780510083f001bef569449808ad55850.tar.zst
crosvm-bc499ec2780510083f001bef569449808ad55850.zip
vhost-net: set backend to null when activate fn quit
Set the backend with null fd can reset the vq in vhost, which
can allow the activate fn to run again.

BUG=None
TEST=launch Crosvm guest with vhost-net. It works fine with iperf test.
TEST=cargo test -p devices

Change-Id: Ida952409147fd6fbd1d8f69b3a88a7ef03051d65
Signed-off-by: Chuanxiao Dong <chuanxiao.dong@intel.corp-partner.google.com>
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/2009523
Reviewed-by: Daniel Verkamp <dverkamp@chromium.org>
Tested-by: kokoro <noreply+kokoro@google.com>
-rw-r--r--devices/src/virtio/vhost/net.rs11
-rw-r--r--vhost/src/net.rs8
2 files changed, 13 insertions, 6 deletions
diff --git a/devices/src/virtio/vhost/net.rs b/devices/src/virtio/vhost/net.rs
index ba24e3d..1107e9f 100644
--- a/devices/src/virtio/vhost/net.rs
+++ b/devices/src/virtio/vhost/net.rs
@@ -201,12 +201,19 @@ where
                                 let activate_vqs = |handle: &U| -> Result<()> {
                                     for idx in 0..NUM_QUEUES {
                                         handle
-                                            .set_backend(idx, &tap)
+                                            .set_backend(idx, Some(&tap))
+                                            .map_err(Error::VhostNetSetBackend)?;
+                                    }
+                                    Ok(())
+                                };
+                                let cleanup_vqs = |handle: &U| -> Result<()> {
+                                    for idx in 0..NUM_QUEUES {
+                                        handle
+                                            .set_backend(idx, None)
                                             .map_err(Error::VhostNetSetBackend)?;
                                     }
                                     Ok(())
                                 };
-                                let cleanup_vqs = |_handle: &U| -> Result<()> { Ok(()) };
                                 let result = worker.run(
                                     queue_evts,
                                     QUEUE_SIZES,
diff --git a/vhost/src/net.rs b/vhost/src/net.rs
index 17ea91a..7d49f17 100644
--- a/vhost/src/net.rs
+++ b/vhost/src/net.rs
@@ -38,7 +38,7 @@ pub trait NetT<T: TapT>: Vhost + AsRawFd + Send + Sized {
     /// # Arguments
     /// * `queue_index` - Index of the queue to modify.
     /// * `fd` - Tap interface that will be used as the backend.
-    fn set_backend(&self, queue_index: usize, fd: &T) -> Result<()>;
+    fn set_backend(&self, queue_index: usize, fd: Option<&T>) -> Result<()>;
 }
 
 impl<T> NetT<T> for Net<T>
@@ -62,10 +62,10 @@ where
         })
     }
 
-    fn set_backend(&self, queue_index: usize, fd: &T) -> Result<()> {
+    fn set_backend(&self, queue_index: usize, fd: Option<&T>) -> Result<()> {
         let vring_file = virtio_sys::vhost_vring_file {
             index: queue_index as u32,
-            fd: fd.as_raw_fd(),
+            fd: fd.map_or(-1, |fd| fd.as_raw_fd()),
         };
 
         // This ioctl is called on a valid vhost_net fd and has its
@@ -127,7 +127,7 @@ pub mod fakes {
             })
         }
 
-        fn set_backend(&self, _queue_index: usize, _fd: &T) -> Result<()> {
+        fn set_backend(&self, _queue_index: usize, _fd: Option<&T>) -> Result<()> {
             Ok(())
         }
     }