From a3f3ad96f2c99fb2987bb9ce4c0365a7a03095b6 Mon Sep 17 00:00:00 2001 From: Adam Jensen Date: Tue, 30 Jan 2024 21:18:27 -0500 Subject: [PATCH] vmm: Implement basic reset capability for net device Signed-off-by: Adam Jensen --- src/vmm/src/devices/virtio/net/device.rs | 41 ++++++++++++++++++------ 1 file changed, 31 insertions(+), 10 deletions(-) diff --git a/src/vmm/src/devices/virtio/net/device.rs b/src/vmm/src/devices/virtio/net/device.rs index 9d8cdfd7372..5ac24ef0e65 100755 --- a/src/vmm/src/devices/virtio/net/device.rs +++ b/src/vmm/src/devices/virtio/net/device.rs @@ -34,7 +34,7 @@ use crate::devices::virtio::net::{ gen, NetError, NetQueue, MAX_BUFFER_SIZE, NET_QUEUE_SIZES, RX_INDEX, TX_INDEX, }; use crate::devices::virtio::queue::{DescriptorChain, Queue}; -use crate::devices::virtio::{ActivateError, TYPE_NET}; +use crate::devices::virtio::{ActivateError, ResetError, TYPE_NET}; use crate::devices::{report_net_event_fail, DeviceError}; use crate::dumbo::pdu::arp::ETH_IPV4_FRAME_LEN; use crate::dumbo::pdu::ethernet::{EthernetFrame, PAYLOAD_OFFSET}; @@ -870,6 +870,15 @@ impl VirtioDevice for Net { fn is_activated(&self) -> bool { self.device_state.is_activated() } + + fn reset(&mut self) -> Result<(), ResetError> { + self.device_state = DeviceState::Inactive; + self.rx_bytes_read = 0; + self.rx_deferred_frame = false; + self.rx_frame_buf = [0u8; MAX_BUFFER_SIZE]; + self.metrics = NetMetricsPerDevice::alloc(self.id.clone()); + Ok(()) + } } #[cfg(test)] @@ -2015,17 +2024,29 @@ pub mod tests { th.activate_net(); let net = th.net.lock().unwrap(); - // Test queues count (TX and RX). - let queues = net.queues(); - assert_eq!(queues.len(), NET_QUEUE_SIZES.len()); - assert_eq!(queues[RX_INDEX].size, th.rxq.size()); - assert_eq!(queues[TX_INDEX].size, th.txq.size()); + let validate = |net: &Net| { + // Test queues count (TX and RX). + let queues = net.queues(); + assert_eq!(queues.len(), NET_QUEUE_SIZES.len()); + assert_eq!(queues[RX_INDEX].size, th.rxq.size()); + assert_eq!(queues[TX_INDEX].size, th.txq.size()); + + // Test corresponding queues events. + assert_eq!(net.queue_events().len(), NET_QUEUE_SIZES.len()); + + // Test interrupts. + assert!(!&net.irq_trigger.has_pending_irq(IrqType::Vring)); + }; + + validate(&net); - // Test corresponding queues events. - assert_eq!(net.queue_events().len(), NET_QUEUE_SIZES.len()); + // Test reset. + let mut net = net; + assert!(net.device_state.is_activated()); + net.reset().unwrap(); + assert!(!net.device_state.is_activated()); - // Test interrupts. - assert!(!&net.irq_trigger.has_pending_irq(IrqType::Vring)); + validate(&net); } #[test]