vmm: Optimize migration for virtio-mem

Copy only the memory ranges that have been plugged through virtio-mem,
allowing for an interesting optimization regarding the time it takes to
migrate a large virtio-mem device. Even if the hotpluggable space is
very large (say 64GiB), if only 1GiB has been previously added to the
VM, only 1GiB will be sent to the destination VM, avoiding the transfer
of the remaining 63GiB which are unused.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
This commit is contained in:
Sebastien Boeuf 2021-09-24 14:30:01 +02:00 committed by Bo Chen
parent 0fb24ea3ae
commit 86f86c5348

View File

@ -66,9 +66,10 @@ use std::{result, str, thread};
use vm_device::Bus;
#[cfg(target_arch = "x86_64")]
use vm_device::BusDevice;
#[cfg(feature = "tdx")]
use vm_memory::GuestMemory;
use vm_memory::{
Address, Bytes, GuestAddress, GuestAddressSpace, GuestMemory, GuestMemoryAtomic,
GuestMemoryRegion,
Address, Bytes, GuestAddress, GuestAddressSpace, GuestMemoryAtomic, GuestMemoryRegion,
};
use vm_migration::{
protocol::{MemoryRange, MemoryRangeTable},
@ -2189,13 +2190,18 @@ impl Vm {
pub fn memory_range_table(&self) -> std::result::Result<MemoryRangeTable, MigratableError> {
let mut table = MemoryRangeTable::default();
let guest_memory = self.memory_manager.lock().as_ref().unwrap().guest_memory();
let mm = self.memory_manager.lock().unwrap();
for region in guest_memory.memory().iter() {
table.push(MemoryRange {
gpa: region.start_addr().raw_value(),
length: region.len() as u64,
});
for memory_zone in mm.memory_zones().values() {
for region in memory_zone.regions() {
table.push(MemoryRange {
gpa: region.start_addr().raw_value(),
length: region.len() as u64,
});
}
if let Some(virtio_mem_zone) = memory_zone.virtio_mem_zone() {
table.extend(virtio_mem_zone.plugged_ranges());
}
}
Ok(table)