From 86f86c53484f0c5f297fbbda56c73069dd76bf83 Mon Sep 17 00:00:00 2001 From: Sebastien Boeuf Date: Fri, 24 Sep 2021 14:30:01 +0200 Subject: [PATCH] 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 --- vmm/src/vm.rs | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/vmm/src/vm.rs b/vmm/src/vm.rs index d08da9818..35ccd1a94 100644 --- a/vmm/src/vm.rs +++ b/vmm/src/vm.rs @@ -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 { 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)