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 <keiichiw@chromium.org>
Tested-by: kokoro <noreply+kokoro@google.com>
Reviewed-by: Daniel Verkamp <dverkamp@chromium.org>
Commit-Queue: Keiichi Watanabe <keiichiw@chromium.org>
This commit is contained in:
Keiichi Watanabe 2021-03-04 02:23:28 +09:00 committed by Commit Bot
parent 19bfe410fa
commit 4d343bbf55
2 changed files with 10 additions and 7 deletions

View file

@ -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")

View file

@ -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) => {