diff options
author | Xiong Zhang <xiong.y.zhang@intel.corp-partner.google.com> | 2019-09-05 19:29:30 +0800 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2019-10-25 23:59:43 +0000 |
commit | 3185ae95dd58f556a836f9e146dfe7b8450749b2 (patch) | |
tree | b3eb1b569650d2a9fda7d864c622a5510e7d6b2a /devices/src/virtio/vhost/worker.rs | |
parent | 3530f2a2bb05f8ccf45d2fa452c9f9f4de547876 (diff) | |
download | crosvm-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/worker.rs')
-rw-r--r-- | devices/src/virtio/vhost/worker.rs | 42 |
1 files changed, 29 insertions, 13 deletions
diff --git a/devices/src/virtio/vhost/worker.rs b/devices/src/virtio/vhost/worker.rs index 54cbb63..26c1449 100644 --- a/devices/src/virtio/vhost/worker.rs +++ b/devices/src/virtio/vhost/worker.rs @@ -5,11 +5,13 @@ use std::os::raw::c_ulonglong; use std::sync::atomic::{AtomicUsize, Ordering}; use std::sync::Arc; +use sync::Mutex; use sys_util::{EventFd, PollContext, PollToken}; use vhost::Vhost; use super::{Error, Result}; +use crate::pci::MsixConfig; use crate::virtio::{Queue, INTERRUPT_STATUS_USED_RING}; /// Worker that takes care of running the vhost device. This mainly involves forwarding interrupts @@ -19,10 +21,11 @@ use crate::virtio::{Queue, INTERRUPT_STATUS_USED_RING}; pub struct Worker<T: Vhost> { queues: Vec<Queue>, vhost_handle: T, - vhost_interrupt: EventFd, + vhost_interrupt: Vec<EventFd>, interrupt_status: Arc<AtomicUsize>, interrupt_evt: EventFd, interrupt_resample_evt: EventFd, + msix_config: Option<Arc<Mutex<MsixConfig>>>, acked_features: u64, } @@ -30,10 +33,11 @@ impl<T: Vhost> Worker<T> { pub fn new( queues: Vec<Queue>, vhost_handle: T, - vhost_interrupt: EventFd, + vhost_interrupt: Vec<EventFd>, interrupt_status: Arc<AtomicUsize>, interrupt_evt: EventFd, interrupt_resample_evt: EventFd, + msix_config: Option<Arc<Mutex<MsixConfig>>>, acked_features: u64, ) -> Worker<T> { Worker { @@ -43,11 +47,20 @@ impl<T: Vhost> Worker<T> { interrupt_status, interrupt_evt, interrupt_resample_evt, + msix_config, acked_features, } } - fn signal_used_queue(&self) { + fn signal_used_queue(&self, vector: u16) { + if let Some(msix_config) = &self.msix_config { + let mut msix_config = msix_config.lock(); + if msix_config.enabled() { + msix_config.trigger(vector); + return; + } + } + self.interrupt_status .fetch_or(INTERRUPT_STATUS_USED_RING as usize, Ordering::SeqCst); self.interrupt_evt.write(1).unwrap(); @@ -103,7 +116,7 @@ impl<T: Vhost> Worker<T> { .set_vring_base(queue_index, 0) .map_err(Error::VhostSetVringBase)?; self.vhost_handle - .set_vring_call(queue_index, &self.vhost_interrupt) + .set_vring_call(queue_index, &self.vhost_interrupt[queue_index]) .map_err(Error::VhostSetVringCall)?; self.vhost_handle .set_vring_kick(queue_index, &queue_evts[queue_index]) @@ -114,27 +127,33 @@ impl<T: Vhost> Worker<T> { #[derive(PollToken)] enum Token { - VhostIrq, + VhostIrqi { index: usize }, InterruptResample, Kill, } let poll_ctx: PollContext<Token> = PollContext::build_with(&[ - (&self.vhost_interrupt, Token::VhostIrq), (&self.interrupt_resample_evt, Token::InterruptResample), (&kill_evt, Token::Kill), ]) .map_err(Error::CreatePollContext)?; + for (index, vhost_int) in self.vhost_interrupt.iter().enumerate() { + poll_ctx + .add(vhost_int, Token::VhostIrqi { index }) + .map_err(Error::CreatePollContext)?; + } + 'poll: loop { let events = poll_ctx.wait().map_err(Error::PollError)?; - let mut needs_interrupt = false; for event in events.iter_readable() { match event.token() { - Token::VhostIrq => { - needs_interrupt = true; - self.vhost_interrupt.read().map_err(Error::VhostIrqRead)?; + Token::VhostIrqi { index } => { + self.vhost_interrupt[index] + .read() + .map_err(Error::VhostIrqRead)?; + self.signal_used_queue(self.queues[index].vector); } Token::InterruptResample => { let _ = self.interrupt_resample_evt.read(); @@ -145,9 +164,6 @@ impl<T: Vhost> Worker<T> { Token::Kill => break 'poll, } } - if needs_interrupt { - self.signal_used_queue(); - } } Ok(()) } |