Skip to content

Commit c0f9be6

Browse files
committed
devices: schedule PostMigrationAnnouncer of all devices
After this change switches in a network should find the new location of a VM quicker. On-behalf-of: SAP [email protected] Signed-off-by: Sebastian Eydam <[email protected]>
1 parent bc3b35c commit c0f9be6

File tree

2 files changed

+52
-5
lines changed

2 files changed

+52
-5
lines changed

virtio-devices/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,8 @@ pub use self::balloon::Balloon;
4242
pub use self::block::{Block, BlockState};
4343
pub use self::console::{Console, ConsoleResizer, Endpoint};
4444
pub use self::device::{
45-
DmaRemapping, VirtioCommon, VirtioDevice, VirtioInterrupt, VirtioInterruptType,
46-
VirtioSharedMemoryList,
45+
DmaRemapping, PostMigrationAnnouncer, VirtioCommon, VirtioDevice, VirtioInterrupt,
46+
VirtioInterruptType, VirtioSharedMemoryList,
4747
};
4848
pub use self::epoll_helper::{
4949
EPOLL_HELPER_EVENT_LAST, EpollHelper, EpollHelperError, EpollHelperHandler,

vmm/src/device_manager.rs

Lines changed: 50 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,11 @@ use std::num::Wrapping;
1616
use std::os::unix::fs::OpenOptionsExt;
1717
use std::os::unix::io::{AsRawFd, FromRawFd};
1818
use std::path::{Path, PathBuf};
19-
use std::result;
2019
use std::sync::{Arc, Mutex};
20+
use std::time::Duration;
2121
#[cfg(not(target_arch = "riscv64"))]
2222
use std::time::Instant;
23+
use std::{result, thread};
2324

2425
use acpi_tables::sdt::GenericAddress;
2526
use acpi_tables::{Aml, aml};
@@ -90,8 +91,8 @@ use vfio_ioctls::{VfioContainer, VfioDevice, VfioDeviceFd};
9091
use virtio_devices::transport::{VirtioPciDevice, VirtioPciDeviceActivator, VirtioTransport};
9192
use virtio_devices::vhost_user::VhostUserConfig;
9293
use virtio_devices::{
93-
AccessPlatformMapping, ActivateError, Block, Endpoint, IommuMapping, VdpaDmaMapping,
94-
VirtioMemMappingSource,
94+
AccessPlatformMapping, ActivateError, Block, Endpoint, IommuMapping, PostMigrationAnnouncer,
95+
VdpaDmaMapping, VirtioMemMappingSource,
9596
};
9697
use vm_allocator::{AddressAllocator, SystemAllocator};
9798
use vm_device::dma_mapping::ExternalDmaMapping;
@@ -5063,6 +5064,48 @@ impl DeviceManager {
50635064
self.vfio_container = None;
50645065
}
50655066
}
5067+
5068+
// Calls the PostMigrationAnnouncers of each device that has one, and schedules
5069+
// periodic announcements. Currently only network devices use this to announce
5070+
// the new location of the VM to the network.
5071+
pub fn post_migration_announce(&self) {
5072+
let mut announcers: Vec<Box<dyn PostMigrationAnnouncer>> = self
5073+
.virtio_devices
5074+
.iter()
5075+
.filter_map(|dev| dev.virtio_device.lock().unwrap().post_migration_announcer())
5076+
.collect();
5077+
5078+
announcers.iter_mut().for_each(|a| a.announce_once());
5079+
schedule_post_migration_announces(announcers, 4, 50, 100, 450);
5080+
}
5081+
}
5082+
5083+
// We could make this announcer configurable.
5084+
fn schedule_post_migration_announces(
5085+
mut announcers: Vec<Box<dyn PostMigrationAnnouncer>>,
5086+
rounds: u32,
5087+
initial_ms: u64,
5088+
step_ms: u64,
5089+
max_ms: u64,
5090+
) {
5091+
if announcers.is_empty() || rounds == 0 {
5092+
return;
5093+
}
5094+
5095+
let _ = thread::Builder::new()
5096+
.name("post-migration-announcers".to_string())
5097+
.spawn(move || {
5098+
for round in 0..rounds {
5099+
// The first announce is done synchronous, thus we sleep at the
5100+
// start of the loop.
5101+
5102+
let delay = (initial_ms + (round as u64) * step_ms).min(max_ms);
5103+
let delay = Duration::from_millis(delay);
5104+
thread::sleep(delay);
5105+
5106+
announcers.iter_mut().for_each(|a| a.announce_once());
5107+
}
5108+
});
50665109
}
50675110

50685111
#[cfg(feature = "ivshmem")]
@@ -5406,6 +5449,10 @@ impl Pausable for DeviceManager {
54065449
}
54075450

54085451
fn resume(&mut self) -> result::Result<(), MigratableError> {
5452+
// Before resuming the devices, we active the post migration announcers
5453+
// of devices that have one.
5454+
self.post_migration_announce();
5455+
54095456
for (_, device_node) in self.device_tree.lock().unwrap().iter() {
54105457
if let Some(migratable) = &device_node.migratable {
54115458
migratable.lock().unwrap().resume()?;

0 commit comments

Comments
 (0)