mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2026-08-05 02:19:16 +00:00
virtio-devices: Test activator failure releases barrier
Feed BadActivate into VirtioPciDeviceActivator and assert that the error propagates, device_activated stays false, DEVICE_NEEDS_RESET is set in status, a single Config interrupt is delivered, and a thread waiting on the activation barrier unblocks. The barrier release is the deadlock fixed by the NEEDS_RESET on activation failure change. Assisted-by: Claude:Opus-4.7 Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
This commit is contained in:
committed by
Rob Bradford
parent
7cdb724346
commit
64c552cc96
@@ -1365,6 +1365,7 @@ mod unit_tests {
|
|||||||
use vm_device::interrupt::InterruptSourceConfig;
|
use vm_device::interrupt::InterruptSourceConfig;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use crate::{ActivateError, DEVICE_NEEDS_RESET};
|
||||||
|
|
||||||
struct TestInterruptSourceGroup {
|
struct TestInterruptSourceGroup {
|
||||||
event_fd: EventFd,
|
event_fd: EventFd,
|
||||||
@@ -1594,4 +1595,30 @@ mod unit_tests {
|
|||||||
};
|
};
|
||||||
(activator, status, device_activated, interrupt, barrier)
|
(activator, status, device_activated, interrupt, barrier)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn activate_failure_marks_needs_reset_and_releases_barrier() {
|
||||||
|
let (activator, status, device_activated, interrupt, barrier) =
|
||||||
|
make_activator(Err(ActivateError::BadActivate));
|
||||||
|
|
||||||
|
// Simulate the vCPU thread blocked on the activation
|
||||||
|
// barrier after writing DRIVER_OK.
|
||||||
|
let waiter = std::thread::spawn(move || barrier.wait());
|
||||||
|
|
||||||
|
let result = activator.activate();
|
||||||
|
|
||||||
|
assert!(matches!(result, Err(ActivateError::BadActivate)));
|
||||||
|
assert!(!device_activated.load(Ordering::SeqCst));
|
||||||
|
assert_ne!(
|
||||||
|
status.load(Ordering::SeqCst) & (DEVICE_NEEDS_RESET as u8),
|
||||||
|
0
|
||||||
|
);
|
||||||
|
let triggers = interrupt.triggers.lock().unwrap();
|
||||||
|
assert_eq!(triggers.len(), 1);
|
||||||
|
assert!(matches!(triggers[0], VirtioInterruptType::Config));
|
||||||
|
|
||||||
|
// The barrier waiter must complete, showing the activator
|
||||||
|
// did not deadlock the vCPU thread.
|
||||||
|
waiter.join().expect("barrier waiter deadlocked");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user