From 4d343bbf5594296b45f37648413ed657da000a56 Mon Sep 17 00:00:00 2001 From: Keiichi Watanabe Date: Thu, 4 Mar 2021 02:23:28 +0900 Subject: [PATCH] devices: virtio: Skip setting up unused virtqueues While a host virtio device provides |num_queues| virtqueues, a guest virtio driver doesn't necessarily use all of them. For example, the virtio-blk driver uses only |nr_cpu_ids| virtqueues at most [1]. To avoid checking whether each queue is ready in each device implementation, we can filter them before starting device activation. [1]: https://patchwork.kernel.org/project/linux-block/cover/1553682995-5682-1-git-send-email-dongli.zhang@oracle.com/ BUG=b:179671351, b:181753022 TEST=CQ Change-Id: I29d21d8d9db2d99aa9591ca55c18d06d2368797e Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/2732735 Tested-by: Keiichi Watanabe Tested-by: kokoro Reviewed-by: Daniel Verkamp Commit-Queue: Keiichi Watanabe --- devices/src/virtio/block_async.rs | 1 - devices/src/virtio/virtio_pci_device.rs | 16 ++++++++++------ 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/devices/src/virtio/block_async.rs b/devices/src/virtio/block_async.rs index d1e1e5d6d3..0ea2e02653 100644 --- a/devices/src/virtio/block_async.rs +++ b/devices/src/virtio/block_async.rs @@ -485,7 +485,6 @@ fn run_worker( let queue_handlers = queues .into_iter() - .filter(|q| q.ready) .map(|q| Rc::new(RefCell::new(q))) .zip(queue_evts.into_iter().map(|e| { EventAsync::new(e.0, &ex).expect("Failed to create async event for queue") diff --git a/devices/src/virtio/virtio_pci_device.rs b/devices/src/virtio/virtio_pci_device.rs index a826e4c748..9ba9f2fbd3 100644 --- a/devices/src/virtio/virtio_pci_device.rs +++ b/devices/src/virtio/virtio_pci_device.rs @@ -698,12 +698,16 @@ impl PciDevice for VirtioPciDevice { match self.clone_queue_evts() { Ok(queue_evts) => { - self.device.activate( - mem, - interrupt, - self.queues.clone(), - queue_evts, - ); + // Use ready queues and their events. + let (queues, queue_evts) = self + .queues + .clone() + .into_iter() + .zip(queue_evts.into_iter()) + .filter(|(q, _)| q.ready) + .unzip(); + + self.device.activate(mem, interrupt, queues, queue_evts); self.device_activated = true; } Err(e) => {