diff options
author | Xiong Zhang <xiong.y.zhang@intel.corp-partner.google.com> | 2019-12-30 14:39:39 +0800 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2020-02-19 06:09:41 +0000 |
commit | 79f10170da3c131ee23eee3018f981811e09a4cc (patch) | |
tree | 055c6fcc77ae20fac47cbda694a9f32c76fd1549 /devices/src/virtio | |
parent | 2dae56768c0dcfb57ff07c051f5785162632073e (diff) | |
download | crosvm-79f10170da3c131ee23eee3018f981811e09a4cc.tar crosvm-79f10170da3c131ee23eee3018f981811e09a4cc.tar.gz crosvm-79f10170da3c131ee23eee3018f981811e09a4cc.tar.bz2 crosvm-79f10170da3c131ee23eee3018f981811e09a4cc.tar.lz crosvm-79f10170da3c131ee23eee3018f981811e09a4cc.tar.xz crosvm-79f10170da3c131ee23eee3018f981811e09a4cc.tar.zst crosvm-79f10170da3c131ee23eee3018f981811e09a4cc.zip |
virtio: Inject virtio-blk interrupt quickly
Current blk interrupt is injected into guest after device handle a batch of requests. While this patch injects interrupt at the end of each request. So guest block will get much more interrupts and could handle request more quickly. With this patch, the guest fio read test improves 13%, while fio write doesn't get better. BUG=none TEST=run fio_read and fio_write in guest Change-Id: Ib0bd23e624dfc5d940d6cc124468b898d8ba128e Signed-off-by: Xiong Zhang <xiong.y.zhang@intel.corp-partner.google.com> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/2008338 Reviewed-by: Daniel Verkamp <dverkamp@chromium.org> Tested-by: kokoro <noreply+kokoro@google.com>
Diffstat (limited to 'devices/src/virtio')
-rw-r--r-- | devices/src/virtio/block.rs | 13 | ||||
-rw-r--r-- | devices/src/virtio/queue.rs | 14 |
2 files changed, 19 insertions, 8 deletions
diff --git a/devices/src/virtio/block.rs b/devices/src/virtio/block.rs index 30cf4f7..65be6d5 100644 --- a/devices/src/virtio/block.rs +++ b/devices/src/virtio/block.rs @@ -298,13 +298,13 @@ impl Worker { queue_index: usize, flush_timer: &mut TimerFd, flush_timer_armed: &mut bool, - ) -> bool { + ) { let queue = &mut self.queues[queue_index]; let disk_size = self.disk_size.lock(); - let mut needs_interrupt = false; while let Some(avail_desc) = queue.pop(&self.mem) { + queue.set_notify(&self.mem, false); let desc_index = avail_desc.index; let len = match Worker::process_one_request( @@ -325,10 +325,9 @@ impl Worker { }; queue.add_used(&self.mem, desc_index, len as u32); - needs_interrupt = true; + self.interrupt.signal_used_queue(queue.vector); + queue.set_notify(&self.mem, true); } - - needs_interrupt } fn resize(&mut self, new_size: u64) -> DiskControlResult { @@ -419,9 +418,7 @@ impl Worker { error!("failed reading queue EventFd: {}", e); break 'poll; } - if self.process_queue(0, &mut flush_timer, &mut flush_timer_armed) { - self.interrupt.signal_used_queue(self.queues[0].vector); - } + self.process_queue(0, &mut flush_timer, &mut flush_timer_armed); } Token::ControlRequest => { let req = match self.control_socket.recv() { diff --git a/devices/src/virtio/queue.rs b/devices/src/virtio/queue.rs index 21cf63e..b3c738c 100644 --- a/devices/src/virtio/queue.rs +++ b/devices/src/virtio/queue.rs @@ -15,6 +15,8 @@ const VIRTQ_DESC_F_WRITE: u16 = 0x2; #[allow(dead_code)] const VIRTQ_DESC_F_INDIRECT: u16 = 0x4; +const VIRTQ_USED_F_NO_NOTIFY: 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. pub struct DescIter<'a> { @@ -381,4 +383,16 @@ impl Queue { mem.write_obj_at_addr(self.next_used.0 as u16, used_ring.unchecked_add(2)) .unwrap(); } + + /// Enable / Disable guest notify device that requests are available on + /// the descriptor chain. + pub fn set_notify(&mut self, mem: &GuestMemory, enable: bool) { + let mut used_flags: u16 = mem.read_obj_from_addr(self.used_ring).unwrap(); + if enable { + used_flags &= !VIRTQ_USED_F_NO_NOTIFY; + } else { + used_flags |= VIRTQ_USED_F_NO_NOTIFY; + } + mem.write_obj_at_addr(used_flags, self.used_ring).unwrap(); + } } |