vmm: Activate virtio device from VMM thread

When a device is ready to be activated signal to the VMM thread via an
EventFd that there is a device to be activated. When the VMM receives a
notification on the EventFd that there is a device to be activated
notify the device manager to attempt to activate any devices that have
not been activated.

As a side effect the VMM thread will create the virtio device threads.

Fixes: #1863

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
This commit is contained in:
Rob Bradford
2020-11-09 13:29:05 +00:00
parent dee42ebb29
commit 03db48306b
4 changed files with 114 additions and 11 deletions

View File

@@ -776,6 +776,10 @@ pub struct DeviceManager {
// Possible handle to the virtio-balloon device
balloon: Option<Arc<Mutex<virtio_devices::Balloon>>>,
// Virtio Device activation EventFd to allow the VMM thread to trigger device
// activation and thus start the threads from the VMM thread
activate_evt: EventFd,
}
impl DeviceManager {
@@ -788,6 +792,7 @@ impl DeviceManager {
reset_evt: &EventFd,
seccomp_action: SeccompAction,
#[cfg(feature = "acpi")] numa_nodes: NumaNodes,
activate_evt: &EventFd,
) -> DeviceManagerResult<Arc<Mutex<Self>>> {
let device_tree = Arc::new(Mutex::new(DeviceTree::new()));
@@ -844,6 +849,9 @@ impl DeviceManager {
#[cfg(feature = "acpi")]
numa_nodes,
balloon: None,
activate_evt: activate_evt
.try_clone()
.map_err(DeviceManagerError::EventFd)?,
};
#[cfg(feature = "acpi")]
@@ -2739,6 +2747,9 @@ impl DeviceManager {
iommu_mapping_cb,
interrupt_manager,
pci_device_bdf,
self.activate_evt
.try_clone()
.map_err(DeviceManagerError::EventFd)?,
)
.map_err(DeviceManagerError::VirtioDevice)?;
@@ -2834,6 +2845,18 @@ impl DeviceManager {
Ok(())
}
pub fn activate_virtio_devices(&self) -> DeviceManagerResult<()> {
// Find virtio pci devices and activate any pending ones
for (_, any_device) in self.pci_devices.iter() {
if let Ok(virtio_pci_device) =
Arc::clone(any_device).downcast::<Mutex<VirtioPciDevice>>()
{
virtio_pci_device.lock().unwrap().maybe_activate();
}
}
Ok(())
}
pub fn notify_hotplug(
&self,
_notification_type: HotPlugNotificationFlags,