From 9f7e38de575e1b6fa7b009489c554b5d27de401a Mon Sep 17 00:00:00 2001 From: Xiong Zhang Date: Sun, 19 Jan 2020 16:45:32 +0800 Subject: Virtio: Add virtio block irq suppress The flag in avail descriptor supplies irq suppress, it could reduce irq injection from device, so many redundant interrupts could be removed from guest, then improve guest performance. BUG=None TEST=run fio read and fio write in guest Change-Id: I68789d8ca24d0e84d0b446db65057f4da2fac56f Signed-off-by: Xiong Zhang Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/2008339 Tested-by: kokoro Reviewed-by: Daniel Verkamp --- devices/src/virtio/block.rs | 2 +- devices/src/virtio/queue.rs | 20 +++++++++++++++++++- 2 files changed, 20 insertions(+), 2 deletions(-) (limited to 'devices') diff --git a/devices/src/virtio/block.rs b/devices/src/virtio/block.rs index 65be6d5..1e9c63e 100644 --- a/devices/src/virtio/block.rs +++ b/devices/src/virtio/block.rs @@ -325,7 +325,7 @@ impl Worker { }; queue.add_used(&self.mem, desc_index, len as u32); - self.interrupt.signal_used_queue(queue.vector); + queue.trigger_interrupt(&self.mem, &self.interrupt); queue.set_notify(&self.mem, true); } } diff --git a/devices/src/virtio/queue.rs b/devices/src/virtio/queue.rs index b3c738c..15dc3e1 100644 --- a/devices/src/virtio/queue.rs +++ b/devices/src/virtio/queue.rs @@ -8,7 +8,7 @@ use std::sync::atomic::{fence, Ordering}; use sys_util::{error, GuestAddress, GuestMemory}; -use super::VIRTIO_MSI_NO_VECTOR; +use super::{Interrupt, VIRTIO_MSI_NO_VECTOR}; const VIRTQ_DESC_F_NEXT: u16 = 0x1; const VIRTQ_DESC_F_WRITE: u16 = 0x2; @@ -16,6 +16,7 @@ const VIRTQ_DESC_F_WRITE: u16 = 0x2; const VIRTQ_DESC_F_INDIRECT: u16 = 0x4; const VIRTQ_USED_F_NO_NOTIFY: u16 = 0x1; +const VIRTQ_AVAIL_F_NO_INTERRUPT: u16 = 0x1; /// An iterator over a single descriptor chain. Not to be confused with AvailIter, /// which iterates over the descriptor chain heads in a queue. @@ -395,4 +396,21 @@ impl Queue { } mem.write_obj_at_addr(used_flags, self.used_ring).unwrap(); } + + // Check Whether guest enable interrupt injection or not. + fn available_interrupt_enabled(&self, mem: &GuestMemory) -> bool { + let avail_flags: u16 = mem.read_obj_from_addr(self.avail_ring).unwrap(); + if avail_flags & VIRTQ_AVAIL_F_NO_INTERRUPT == VIRTQ_AVAIL_F_NO_INTERRUPT { + false + } else { + true + } + } + + /// inject interrupt into guest on this queue + pub fn trigger_interrupt(&self, mem: &GuestMemory, interrupt: &Interrupt) { + if self.available_interrupt_enabled(mem) { + interrupt.signal_used_queue(self.vector); + } + } } -- cgit 1.4.1