Skip to content

Commit

Permalink
vmm: Implement basic reset capability for net device
Browse files Browse the repository at this point in the history
Signed-off-by: Adam Jensen <[email protected]>
  • Loading branch information
acj committed Jan 21, 2024
1 parent 6791d55 commit 1d1d916
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 10 deletions.
5 changes: 4 additions & 1 deletion src/vmm/src/devices/virtio/mmio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,10 @@ impl MmioTransport {
let mut device_status = self.device_status;
let reset_result = self.locked_device().reset();
match reset_result {
Some((_interrupt_evt, mut _queue_evts)) => {}
Some((_interrupt_evt, mut _queue_evts)) => {
// The device MUST initialize device status to 0 upon reset.
device_status = INIT;
}
None => {
device_status |= FAILED;
}
Expand Down
50 changes: 41 additions & 9 deletions src/vmm/src/devices/virtio/net/device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -870,6 +870,26 @@ impl VirtioDevice for Net {
fn is_activated(&self) -> bool {
self.device_state.is_activated()
}

fn reset(&mut self) -> Option<(EventFd, Vec<EventFd>)> {
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());

let queue_evts: Vec<_> = self
.queue_evts
.iter()
.filter_map(|q| q.try_clone().ok())
.collect();

if let Ok(irq_evt) = self.irq_trigger.irq_evt.try_clone() {
Some((irq_evt, queue_evts))
} else {
None
}
}
}

#[cfg(test)]
Expand Down Expand Up @@ -2015,17 +2035,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());
let (_interrupt_evt, _queue_evts) = net.reset().unwrap();
assert!(!net.device_state.is_activated());

// Test interrupts.
assert!(!&net.irq_trigger.has_pending_irq(IrqType::Vring));
validate(&net);
}

#[test]
Expand Down

0 comments on commit 1d1d916

Please sign in to comment.