summary refs log tree commit diff
path: root/devices/src/virtio/vhost/worker.rs
diff options
context:
space:
mode:
authorZide Chen <zide.chen@intel.corp-partner.google.com>2019-10-15 14:32:23 -0700
committerCommit Bot <commit-bot@chromium.org>2019-10-25 23:59:45 +0000
commit8a7e4e902a4950b060ea23b40c0dfce7bfa1b2cb (patch)
tree67764e974ad0e28021f7e7352ab6e1e759e650cc /devices/src/virtio/vhost/worker.rs
parent3185ae95dd58f556a836f9e146dfe7b8450749b2 (diff)
downloadcrosvm-8a7e4e902a4950b060ea23b40c0dfce7bfa1b2cb.tar
crosvm-8a7e4e902a4950b060ea23b40c0dfce7bfa1b2cb.tar.gz
crosvm-8a7e4e902a4950b060ea23b40c0dfce7bfa1b2cb.tar.bz2
crosvm-8a7e4e902a4950b060ea23b40c0dfce7bfa1b2cb.tar.lz
crosvm-8a7e4e902a4950b060ea23b40c0dfce7bfa1b2cb.tar.xz
crosvm-8a7e4e902a4950b060ea23b40c0dfce7bfa1b2cb.tar.zst
crosvm-8a7e4e902a4950b060ea23b40c0dfce7bfa1b2cb.zip
devices: implement dedicated Interrupt struct for virtio Worker
The code to inject interrupt to the guest can be generic to all
virtio devices. This patch:

- move those guest interrupt related fields out of Worker structure and
  put in a separate file, making the worker code cleaner.
- remove redandant functions across virtio devices: signal_used_queue(),
  signal_config_changed(), etc.

BUG=chromium:854765
TEST=sanity test on eve and Linux
TEST=cargo test -p devices

Change-Id: I8e9f760f2057f192fdc74d16a59fea2e6b08c194
Signed-off-by: Zide Chen <zide.chen@intel.corp-partner.google.com>
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/1869553
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.rs42
1 files changed, 12 insertions, 30 deletions
diff --git a/devices/src/virtio/vhost/worker.rs b/devices/src/virtio/vhost/worker.rs
index 26c1449..e88b929 100644
--- a/devices/src/virtio/vhost/worker.rs
+++ b/devices/src/virtio/vhost/worker.rs
@@ -3,7 +3,7 @@
 // found in the LICENSE file.
 
 use std::os::raw::c_ulonglong;
-use std::sync::atomic::{AtomicUsize, Ordering};
+use std::sync::atomic::AtomicUsize;
 use std::sync::Arc;
 use sync::Mutex;
 
@@ -12,20 +12,17 @@ use vhost::Vhost;
 
 use super::{Error, Result};
 use crate::pci::MsixConfig;
-use crate::virtio::{Queue, INTERRUPT_STATUS_USED_RING};
+use crate::virtio::{Interrupt, Queue};
 
 /// Worker that takes care of running the vhost device.  This mainly involves forwarding interrupts
 /// from the vhost driver to the guest VM because crosvm only supports the virtio-mmio transport,
 /// which requires a bit to be set in the interrupt status register before triggering the interrupt
 /// and the vhost driver doesn't do this for us.
 pub struct Worker<T: Vhost> {
+    interrupt: Interrupt,
     queues: Vec<Queue>,
     vhost_handle: T,
     vhost_interrupt: Vec<EventFd>,
-    interrupt_status: Arc<AtomicUsize>,
-    interrupt_evt: EventFd,
-    interrupt_resample_evt: EventFd,
-    msix_config: Option<Arc<Mutex<MsixConfig>>>,
     acked_features: u64,
 }
 
@@ -41,31 +38,19 @@ impl<T: Vhost> Worker<T> {
         acked_features: u64,
     ) -> Worker<T> {
         Worker {
+            interrupt: Interrupt::new(
+                interrupt_status,
+                interrupt_evt,
+                interrupt_resample_evt,
+                msix_config,
+            ),
             queues,
             vhost_handle,
             vhost_interrupt,
-            interrupt_status,
-            interrupt_evt,
-            interrupt_resample_evt,
-            msix_config,
             acked_features,
         }
     }
 
-    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();
-    }
-
     pub fn run<F>(
         &mut self,
         queue_evts: Vec<EventFd>,
@@ -133,7 +118,7 @@ impl<T: Vhost> Worker<T> {
         }
 
         let poll_ctx: PollContext<Token> = PollContext::build_with(&[
-            (&self.interrupt_resample_evt, Token::InterruptResample),
+            (self.interrupt.get_resample_evt(), Token::InterruptResample),
             (&kill_evt, Token::Kill),
         ])
         .map_err(Error::CreatePollContext)?;
@@ -153,13 +138,10 @@ impl<T: Vhost> Worker<T> {
                         self.vhost_interrupt[index]
                             .read()
                             .map_err(Error::VhostIrqRead)?;
-                        self.signal_used_queue(self.queues[index].vector);
+                        self.interrupt.signal_used_queue(self.queues[index].vector);
                     }
                     Token::InterruptResample => {
-                        let _ = self.interrupt_resample_evt.read();
-                        if self.interrupt_status.load(Ordering::SeqCst) != 0 {
-                            self.interrupt_evt.write(1).unwrap();
-                        }
+                        self.interrupt.interrupt_resample();
                     }
                     Token::Kill => break 'poll,
                 }