Skip to content

Commit 7427a7d

Browse files
committed
refactor: use VirtioInterrupt in VirtIO devices
VirtIO devices assume they're operating under an MMIO transport and as a consequence they use IrqTrigger as interrupts. Switch that to using VirtioInterrupt for all VirtIO device objects. Only assume a VirtioInterrupt is an IrqTrigger in MMIO specific code. Signed-off-by: Babis Chalios <bchalios@amazon.es>
1 parent f297dd7 commit 7427a7d

24 files changed

+263
-140
lines changed

src/vmm/src/device_manager/mmio.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -505,7 +505,7 @@ impl MMIODeviceManager {
505505
.unwrap();
506506
if vsock.is_activated() {
507507
info!("kick vsock {id}.");
508-
vsock.signal_used_queue().unwrap();
508+
vsock.signal_used_queue(0).unwrap();
509509
}
510510
}
511511
TYPE_RNG => {
@@ -525,6 +525,7 @@ impl MMIODeviceManager {
525525
#[cfg(test)]
526526
mod tests {
527527

528+
use std::ops::Deref;
528529
use std::sync::Arc;
529530

530531
use vmm_sys_util::eventfd::EventFd;
@@ -534,6 +535,7 @@ mod tests {
534535
use crate::devices::virtio::ActivateError;
535536
use crate::devices::virtio::device::VirtioDevice;
536537
use crate::devices::virtio::queue::Queue;
538+
use crate::devices::virtio::transport::VirtioInterrupt;
537539
use crate::devices::virtio::transport::mmio::IrqTrigger;
538540
use crate::test_utils::multi_region_mem_raw;
539541
use crate::vstate::kvm::Kvm;
@@ -620,10 +622,8 @@ mod tests {
620622
&self.queue_evts
621623
}
622624

623-
fn interrupt_trigger(&self) -> &IrqTrigger {
624-
self.interrupt_trigger
625-
.as_ref()
626-
.expect("Device is not activated")
625+
fn interrupt_trigger(&self) -> &dyn VirtioInterrupt {
626+
self.interrupt_trigger.as_ref().unwrap().deref()
627627
}
628628

629629
fn ack_features_by_page(&mut self, page: u32, value: u32) {
@@ -644,7 +644,7 @@ mod tests {
644644
fn activate(
645645
&mut self,
646646
_: GuestMemoryMmap,
647-
_: Arc<IrqTrigger>,
647+
_: Arc<dyn VirtioInterrupt>,
648648
) -> Result<(), ActivateError> {
649649
Ok(())
650650
}

src/vmm/src/devices/virtio/balloon/device.rs

+18-12
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
22
// SPDX-License-Identifier: Apache-2.0
33

4+
use std::ops::Deref;
45
use std::sync::Arc;
56
use std::time::Duration;
67

@@ -26,7 +27,7 @@ use super::{
2627
use crate::devices::virtio::balloon::BalloonError;
2728
use crate::devices::virtio::device::ActiveState;
2829
use crate::devices::virtio::generated::virtio_config::VIRTIO_F_VERSION_1;
29-
use crate::devices::virtio::transport::mmio::{IrqTrigger, IrqType};
30+
use crate::devices::virtio::transport::{VirtioInterrupt, VirtioInterruptType};
3031
use crate::logger::IncMetric;
3132
use crate::utils::u64_to_usize;
3233
use crate::vstate::memory::{Address, ByteValued, Bytes, GuestAddress, GuestMemoryMmap};
@@ -340,7 +341,7 @@ impl Balloon {
340341
}
341342

342343
if needs_interrupt {
343-
self.signal_used_queue()?;
344+
self.signal_used_queue(INFLATE_INDEX)?;
344345
}
345346

346347
Ok(())
@@ -358,7 +359,7 @@ impl Balloon {
358359
}
359360

360361
if needs_interrupt {
361-
self.signal_used_queue()
362+
self.signal_used_queue(DEFLATE_INDEX)
362363
} else {
363364
Ok(())
364365
}
@@ -402,9 +403,12 @@ impl Balloon {
402403
Ok(())
403404
}
404405

405-
pub(crate) fn signal_used_queue(&self) -> Result<(), BalloonError> {
406+
pub(crate) fn signal_used_queue(&self, qidx: usize) -> Result<(), BalloonError> {
406407
self.interrupt_trigger()
407-
.trigger_irq(IrqType::Vring)
408+
.trigger(VirtioInterruptType::Queue(
409+
qidx.try_into()
410+
.unwrap_or_else(|_| panic!("balloon: invalid queue id: {qidx}")),
411+
))
408412
.map_err(|err| {
409413
METRICS.event_fails.inc();
410414
BalloonError::InterruptError(err)
@@ -429,7 +433,7 @@ impl Balloon {
429433
self.queues[STATS_INDEX]
430434
.add_used(index, 0)
431435
.map_err(BalloonError::Queue)?;
432-
self.signal_used_queue()
436+
self.signal_used_queue(STATS_INDEX)
433437
} else {
434438
error!("Failed to update balloon stats, missing descriptor.");
435439
Ok(())
@@ -441,7 +445,7 @@ impl Balloon {
441445
if self.is_activated() {
442446
self.config_space.num_pages = mib_to_pages(amount_mib)?;
443447
self.interrupt_trigger()
444-
.trigger_irq(IrqType::Config)
448+
.trigger(VirtioInterruptType::Config)
445449
.map_err(BalloonError::InterruptError)
446450
} else {
447451
Err(BalloonError::DeviceNotActive)
@@ -552,12 +556,12 @@ impl VirtioDevice for Balloon {
552556
&self.queue_evts
553557
}
554558

555-
fn interrupt_trigger(&self) -> &IrqTrigger {
556-
&self
557-
.device_state
559+
fn interrupt_trigger(&self) -> &dyn VirtioInterrupt {
560+
self.device_state
558561
.active_state()
559562
.expect("Device is not activated")
560563
.interrupt
564+
.deref()
561565
}
562566

563567
fn read_config(&self, offset: u64, data: &mut [u8]) {
@@ -587,7 +591,7 @@ impl VirtioDevice for Balloon {
587591
fn activate(
588592
&mut self,
589593
mem: GuestMemoryMmap,
590-
interrupt: Arc<IrqTrigger>,
594+
interrupt: Arc<dyn VirtioInterrupt>,
591595
) -> Result<(), ActivateError> {
592596
for q in self.queues.iter_mut() {
593597
q.initialize(&mem)
@@ -1059,7 +1063,9 @@ pub(crate) mod tests {
10591063
assert!(balloon.stats_desc_index.is_some());
10601064
balloon.process_stats_timer_event().unwrap();
10611065
assert!(balloon.stats_desc_index.is_none());
1062-
assert!(balloon.interrupt_trigger().has_pending_irq(IrqType::Vring));
1066+
assert!(balloon.interrupt_trigger().has_pending_interrupt(
1067+
VirtioInterruptType::Queue(STATS_INDEX.try_into().unwrap())
1068+
));
10631069
});
10641070
}
10651071
}

src/vmm/src/devices/virtio/balloon/persist.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use crate::devices::virtio::balloon::device::{BalloonStats, ConfigSpace};
1515
use crate::devices::virtio::device::{ActiveState, DeviceState};
1616
use crate::devices::virtio::persist::VirtioDeviceState;
1717
use crate::devices::virtio::queue::FIRECRACKER_MAX_QUEUE_SIZE;
18-
use crate::devices::virtio::transport::mmio::IrqTrigger;
18+
use crate::devices::virtio::transport::VirtioInterrupt;
1919
use crate::snapshot::Persist;
2020
use crate::vstate::memory::GuestMemoryMmap;
2121

@@ -96,7 +96,7 @@ pub struct BalloonConstructorArgs {
9696
/// Pointer to guest memory.
9797
pub mem: GuestMemoryMmap,
9898
/// Interrupt used from the device.
99-
pub interrupt: Arc<IrqTrigger>,
99+
pub interrupt: Arc<dyn VirtioInterrupt>,
100100
pub restored_from_file: bool,
101101
}
102102

src/vmm/src/devices/virtio/balloon/test_utils.rs

+7-3
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,16 @@
33

44
#![doc(hidden)]
55

6+
#[cfg(test)]
7+
use crate::devices::virtio::device::VirtioDevice;
68
use crate::devices::virtio::test_utils::VirtQueue;
79
#[cfg(test)]
810
use crate::devices::virtio::{balloon::BALLOON_NUM_QUEUES, balloon::Balloon};
911

1012
#[cfg(test)]
1113
pub fn invoke_handler_for_queue_event(b: &mut Balloon, queue_index: usize) {
1214
use crate::devices::virtio::balloon::{DEFLATE_INDEX, INFLATE_INDEX, STATS_INDEX};
13-
use crate::devices::virtio::device::VirtioDevice;
14-
use crate::devices::virtio::transport::mmio::IrqType;
15+
use crate::devices::virtio::transport::VirtioInterruptType;
1516

1617
assert!(queue_index < BALLOON_NUM_QUEUES);
1718
// Trigger the queue event.
@@ -25,7 +26,10 @@ pub fn invoke_handler_for_queue_event(b: &mut Balloon, queue_index: usize) {
2526
};
2627
// Validate the queue operation finished successfully.
2728
let interrupt = b.interrupt_trigger();
28-
assert!(interrupt.has_pending_irq(IrqType::Vring));
29+
assert!(
30+
interrupt
31+
.has_pending_interrupt(VirtioInterruptType::Queue(queue_index.try_into().unwrap()))
32+
);
2933
}
3034

3135
pub fn set_request(queue: &VirtQueue, idx: u16, addr: u64, len: u32, flags: u16) {

src/vmm/src/devices/virtio/block/device.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use super::vhost_user::device::{VhostUserBlock, VhostUserBlockConfig};
1212
use super::virtio::device::{VirtioBlock, VirtioBlockConfig};
1313
use crate::devices::virtio::device::VirtioDevice;
1414
use crate::devices::virtio::queue::Queue;
15-
use crate::devices::virtio::transport::mmio::IrqTrigger;
15+
use crate::devices::virtio::transport::VirtioInterrupt;
1616
use crate::devices::virtio::{ActivateError, TYPE_BLOCK};
1717
use crate::rate_limiter::BucketUpdate;
1818
use crate::snapshot::Persist;
@@ -176,7 +176,7 @@ impl VirtioDevice for Block {
176176
}
177177
}
178178

179-
fn interrupt_trigger(&self) -> &IrqTrigger {
179+
fn interrupt_trigger(&self) -> &dyn VirtioInterrupt {
180180
match self {
181181
Self::Virtio(b) => b.interrupt_trigger(),
182182
Self::VhostUser(b) => b.interrupt_trigger(),
@@ -200,7 +200,7 @@ impl VirtioDevice for Block {
200200
fn activate(
201201
&mut self,
202202
mem: GuestMemoryMmap,
203-
interrupt: Arc<IrqTrigger>,
203+
interrupt: Arc<dyn VirtioInterrupt>,
204204
) -> Result<(), ActivateError> {
205205
match self {
206206
Self::Virtio(b) => b.activate(mem, interrupt),

src/vmm/src/devices/virtio/block/persist.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use serde::{Deserialize, Serialize};
77

88
use super::vhost_user::persist::VhostUserBlockState;
99
use super::virtio::persist::VirtioBlockState;
10-
use crate::devices::virtio::transport::mmio::IrqTrigger;
10+
use crate::devices::virtio::transport::VirtioInterrupt;
1111
use crate::vstate::memory::GuestMemoryMmap;
1212

1313
/// Block device state.
@@ -21,5 +21,5 @@ pub enum BlockState {
2121
#[derive(Debug)]
2222
pub struct BlockConstructorArgs {
2323
pub mem: GuestMemoryMmap,
24-
pub interrupt: Arc<IrqTrigger>,
24+
pub interrupt: Arc<dyn VirtioInterrupt>,
2525
}

src/vmm/src/devices/virtio/block/vhost_user/device.rs

+10-10
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
// Portions Copyright 2019 Intel Corporation. All Rights Reserved.
55
// SPDX-License-Identifier: Apache-2.0
66

7+
use std::ops::Deref;
78
use std::sync::Arc;
89

910
use log::error;
@@ -14,13 +15,12 @@ use vmm_sys_util::eventfd::EventFd;
1415

1516
use super::{NUM_QUEUES, QUEUE_SIZE, VhostUserBlockError};
1617
use crate::devices::virtio::block::CacheType;
17-
use crate::devices::virtio::device::ActiveState;
18-
use crate::devices::virtio::device::{DeviceState, VirtioDevice};
18+
use crate::devices::virtio::device::{ActiveState, DeviceState, VirtioDevice};
1919
use crate::devices::virtio::generated::virtio_blk::{VIRTIO_BLK_F_FLUSH, VIRTIO_BLK_F_RO};
2020
use crate::devices::virtio::generated::virtio_config::VIRTIO_F_VERSION_1;
2121
use crate::devices::virtio::generated::virtio_ring::VIRTIO_RING_F_EVENT_IDX;
2222
use crate::devices::virtio::queue::Queue;
23-
use crate::devices::virtio::transport::mmio::{IrqTrigger, IrqType};
23+
use crate::devices::virtio::transport::{VirtioInterrupt, VirtioInterruptType};
2424
use crate::devices::virtio::vhost_user::{VhostUserHandleBackend, VhostUserHandleImpl};
2525
use crate::devices::virtio::vhost_user_metrics::{
2626
VhostUserDeviceMetrics, VhostUserMetricsPerDevice,
@@ -275,8 +275,8 @@ impl<T: VhostUserHandleBackend> VhostUserBlockImpl<T> {
275275
.map_err(VhostUserBlockError::Vhost)?;
276276
self.config_space = new_config_space;
277277
interrupt
278-
.trigger_irq(IrqType::Config)
279-
.map_err(VhostUserBlockError::IrqTrigger)?;
278+
.trigger(VirtioInterruptType::Config)
279+
.map_err(VhostUserBlockError::Interrupt)?;
280280

281281
let delta_us = get_time_us(ClockType::Monotonic) - start_time;
282282
self.metrics.config_change_time_us.store(delta_us);
@@ -314,12 +314,12 @@ impl<T: VhostUserHandleBackend + Send + 'static> VirtioDevice for VhostUserBlock
314314
&self.queue_evts
315315
}
316316

317-
fn interrupt_trigger(&self) -> &IrqTrigger {
318-
&self
319-
.device_state
317+
fn interrupt_trigger(&self) -> &dyn VirtioInterrupt {
318+
self.device_state
320319
.active_state()
321320
.expect("Device is not initialized")
322321
.interrupt
322+
.deref()
323323
}
324324

325325
fn read_config(&self, offset: u64, data: &mut [u8]) {
@@ -341,7 +341,7 @@ impl<T: VhostUserHandleBackend + Send + 'static> VirtioDevice for VhostUserBlock
341341
fn activate(
342342
&mut self,
343343
mem: GuestMemoryMmap,
344-
interrupt: Arc<IrqTrigger>,
344+
interrupt: Arc<dyn VirtioInterrupt>,
345345
) -> Result<(), ActivateError> {
346346
for q in self.queues.iter_mut() {
347347
q.initialize(&mem)
@@ -357,7 +357,7 @@ impl<T: VhostUserHandleBackend + Send + 'static> VirtioDevice for VhostUserBlock
357357
self.vu_handle.setup_backend(
358358
&mem,
359359
&[(0, &self.queues[0], &self.queue_evts[0])],
360-
&interrupt,
360+
interrupt.clone(),
361361
)
362362
})
363363
.map_err(|err| {

src/vmm/src/devices/virtio/block/vhost_user/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,5 +28,5 @@ pub enum VhostUserBlockError {
2828
/// Error opening eventfd: {0}
2929
EventFd(std::io::Error),
3030
/// Error creating irqfd: {0}
31-
IrqTrigger(std::io::Error),
31+
Interrupt(std::io::Error),
3232
}

0 commit comments

Comments
 (0)