summary refs log tree commit diff
path: root/devices/src/virtio/vhost/vsock.rs
diff options
context:
space:
mode:
authorXiong Zhang <xiong.y.zhang@intel.corp-partner.google.com>2019-09-05 19:29:30 +0800
committerCommit Bot <commit-bot@chromium.org>2019-10-25 23:59:43 +0000
commit3185ae95dd58f556a836f9e146dfe7b8450749b2 (patch)
treeb3eb1b569650d2a9fda7d864c622a5510e7d6b2a /devices/src/virtio/vhost/vsock.rs
parent3530f2a2bb05f8ccf45d2fa452c9f9f4de547876 (diff)
downloadcrosvm-3185ae95dd58f556a836f9e146dfe7b8450749b2.tar
crosvm-3185ae95dd58f556a836f9e146dfe7b8450749b2.tar.gz
crosvm-3185ae95dd58f556a836f9e146dfe7b8450749b2.tar.bz2
crosvm-3185ae95dd58f556a836f9e146dfe7b8450749b2.tar.lz
crosvm-3185ae95dd58f556a836f9e146dfe7b8450749b2.tar.xz
crosvm-3185ae95dd58f556a836f9e146dfe7b8450749b2.tar.zst
crosvm-3185ae95dd58f556a836f9e146dfe7b8450749b2.zip
devices: enable MSI-X for virtio-net and viotio-block devices
- signal_used_queue(): trigger MSI-X interrupts to the guest if MSI-X is
  enabled, otherwise trigger INTx interrupts
- enable MSI-X on vhost-net: allocate one vhost_interrupt for every
  MSI-X vector.

Performance wise, fio random R/W test on eve pixelbook:

           INTx          MSI-X      delta
fio write  8.13MiB/s    9.79MiB/s   +1.66MiB/s (+20%)
fio read   24.35MiB/s   29.3MiB/s   +4.95MiB/s (+20%)

For networking performance (TCP stream), test results on eve pixelbook:

             INTx            MSI-X          delta
iperf3       5.93Gbits/s     6.57Gbits/s    +0.64Gbits/s (+10.7%)
iperf3 -R    5.68Gbits/s     7.37Gbits/s    +1.30Gbits/s (+22.8%)

iperf test results on VM launched from Ubuntu host (client sends only):

             INTx            MSI-X          delta
virtio-net   9.53Gbits/s     11.4 Gbits/s   +1.87Gbits/s (+19.5%)
vhost        28.34Gbits/s    44.43Gbits/s   +16.09Gbits/s (+56.7%)

BUG=chromium:854765
TEST=cargo test -p devices
TEST=tested virtio-net and block on Linux VM and eve pixelbook

Change-Id: Ic4952a094327e6b977f446def8209ea2f796878c
Signed-off-by: Xiong Zhang <xiong.y.zhang@intel.corp-partner.google.com>
Signed-off-by: Zide Chen <zide.chen@intel.corp-partner.google.com>
Signed-off-by: Sainath Grandhi <sainath.grandhi@intel.corp-partner.google.com>
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/1828340
Reviewed-by: Daniel Verkamp <dverkamp@chromium.org>
Tested-by: Daniel Verkamp <dverkamp@chromium.org>
Tested-by: kokoro <noreply+kokoro@google.com>
Commit-Queue: Daniel Verkamp <dverkamp@chromium.org>
Diffstat (limited to 'devices/src/virtio/vhost/vsock.rs')
-rw-r--r--devices/src/virtio/vhost/vsock.rs29
1 files changed, 21 insertions, 8 deletions
diff --git a/devices/src/virtio/vhost/vsock.rs b/devices/src/virtio/vhost/vsock.rs
index b39c368..b4101eb 100644
--- a/devices/src/virtio/vhost/vsock.rs
+++ b/devices/src/virtio/vhost/vsock.rs
@@ -21,13 +21,14 @@ use crate::virtio::{copy_config, Queue, VirtioDevice, TYPE_VSOCK};
 const QUEUE_SIZE: u16 = 256;
 const NUM_QUEUES: usize = 3;
 const QUEUE_SIZES: &[u16] = &[QUEUE_SIZE; NUM_QUEUES];
+const NUM_MSIX_VECTORS: u16 = NUM_QUEUES as u16;
 
 pub struct Vsock {
     worker_kill_evt: Option<EventFd>,
     kill_evt: Option<EventFd>,
     vhost_handle: Option<VhostVsockHandle>,
     cid: u64,
-    interrupt: Option<EventFd>,
+    interrupts: Option<Vec<EventFd>>,
     avail_features: u64,
     acked_features: u64,
 }
@@ -45,12 +46,17 @@ impl Vsock {
             | 1 << virtio_sys::vhost::VIRTIO_F_ANY_LAYOUT
             | 1 << virtio_sys::vhost::VIRTIO_F_VERSION_1;
 
+        let mut interrupts = Vec::new();
+        for _ in 0..NUM_MSIX_VECTORS {
+            interrupts.push(EventFd::new().map_err(Error::VhostIrqCreate)?);
+        }
+
         Ok(Vsock {
             worker_kill_evt: Some(kill_evt.try_clone().map_err(Error::CloneKillEventFd)?),
             kill_evt: Some(kill_evt),
             vhost_handle: Some(handle),
             cid,
-            interrupt: Some(EventFd::new().map_err(Error::VhostIrqCreate)?),
+            interrupts: Some(interrupts),
             avail_features,
             acked_features: 0,
         })
@@ -62,7 +68,7 @@ impl Vsock {
             kill_evt: None,
             vhost_handle: None,
             cid,
-            interrupt: None,
+            interrupts: None,
             avail_features: features,
             acked_features: 0,
         }
@@ -93,8 +99,10 @@ impl VirtioDevice for Vsock {
             keep_fds.push(handle.as_raw_fd());
         }
 
-        if let Some(interrupt) = &self.interrupt {
-            keep_fds.push(interrupt.as_raw_fd());
+        if let Some(interrupt) = &self.interrupts {
+            for vhost_int in interrupt.iter() {
+                keep_fds.push(vhost_int.as_raw_fd());
+            }
         }
 
         if let Some(worker_kill_evt) = &self.worker_kill_evt {
@@ -108,6 +116,10 @@ impl VirtioDevice for Vsock {
         TYPE_VSOCK
     }
 
+    fn msix_vectors(&self) -> u16 {
+        NUM_MSIX_VECTORS
+    }
+
     fn queue_max_sizes(&self) -> &[u16] {
         QUEUE_SIZES
     }
@@ -140,7 +152,7 @@ impl VirtioDevice for Vsock {
         _: GuestMemory,
         interrupt_evt: EventFd,
         interrupt_resample_evt: EventFd,
-        _msix_config: Option<Arc<Mutex<MsixConfig>>>,
+        msix_config: Option<Arc<Mutex<MsixConfig>>>,
         status: Arc<AtomicUsize>,
         queues: Vec<Queue>,
         queue_evts: Vec<EventFd>,
@@ -151,7 +163,7 @@ impl VirtioDevice for Vsock {
         }
 
         if let Some(vhost_handle) = self.vhost_handle.take() {
-            if let Some(interrupt) = self.interrupt.take() {
+            if let Some(interrupts) = self.interrupts.take() {
                 if let Some(kill_evt) = self.worker_kill_evt.take() {
                     let acked_features = self.acked_features;
                     let cid = self.cid;
@@ -164,10 +176,11 @@ impl VirtioDevice for Vsock {
                             let mut worker = Worker::new(
                                 vhost_queues,
                                 vhost_handle,
-                                interrupt,
+                                interrupts,
                                 status,
                                 interrupt_evt,
                                 interrupt_resample_evt,
+                                msix_config,
                                 acked_features,
                             );
                             let activate_vqs = |handle: &VhostVsockHandle| -> Result<()> {