From d771223b2f1c66e16941fc34aff6c2ef7bcfdc29 Mon Sep 17 00:00:00 2001 From: Sebastien Boeuf Date: Tue, 7 Apr 2020 11:19:28 +0200 Subject: [PATCH] vmm: memory: Extend new() to support external backing files Whenever a MemoryManager is restored from a snapshot, the memory regions associated with it might need to directly back the mapped memory for increased performances. If that's the case, a list of external regions is provided and the MemoryManager should simply ignore what's coming from the MemoryConfig. Signed-off-by: Sebastien Boeuf --- vmm/src/memory_manager.rs | 41 ++++++++++++++++++++++++++++++--------- vmm/src/vm.rs | 5 +++-- 2 files changed, 35 insertions(+), 11 deletions(-) diff --git a/vmm/src/memory_manager.rs b/vmm/src/memory_manager.rs index 377835c11..73ba15ae7 100644 --- a/vmm/src/memory_manager.rs +++ b/vmm/src/memory_manager.rs @@ -110,6 +110,10 @@ pub enum Error { /// Cannot create the system allocator CreateSystemAllocator, + + /// The number of external backing files doesn't match the number of + /// memory regions. + InvalidAmountExternalBackingFiles, } pub fn get_host_cpu_phys_bits() -> u8 { @@ -221,7 +225,11 @@ impl BusDevice for MemoryManager { } impl MemoryManager { - pub fn new(fd: Arc, config: &MemoryConfig) -> Result>, Error> { + pub fn new( + fd: Arc, + config: &MemoryConfig, + ext_regions: Option>, + ) -> Result>, Error> { // Init guest memory let arch_mem_regions = arch::arch_memory_regions(config.size); @@ -232,13 +240,28 @@ impl MemoryManager { .collect(); let mut mem_regions = Vec::new(); - for region in ram_regions.iter() { - mem_regions.push(MemoryManager::create_ram_region( - &config.file, - region.0, - region.1, - false, - )?); + if let Some(ext_regions) = &ext_regions { + if ram_regions.len() > ext_regions.len() { + return Err(Error::InvalidAmountExternalBackingFiles); + } + + for region in ext_regions.iter() { + mem_regions.push(MemoryManager::create_ram_region( + &Some(region.backing_file.clone()), + region.start_addr, + region.size as usize, + true, + )?); + } + } else { + for region in ram_regions.iter() { + mem_regions.push(MemoryManager::create_ram_region( + &config.file, + region.0, + region.1, + false, + )?); + } } let guest_memory = @@ -361,7 +384,7 @@ impl MemoryManager { config: &MemoryConfig, source_url: &str, ) -> Result>, Error> { - let memory_manager = MemoryManager::new(fd, config)?; + let memory_manager = MemoryManager::new(fd, config, None)?; let url = Url::parse(source_url).unwrap(); /* url must be valid dir which is verified in recv_vm_snapshot() */ diff --git a/vmm/src/vm.rs b/vmm/src/vm.rs index 4a363c2c6..933de72c9 100755 --- a/vmm/src/vm.rs +++ b/vmm/src/vm.rs @@ -360,8 +360,9 @@ impl Vm { vmm_path: PathBuf, ) -> Result { let (kvm, fd) = Vm::kvm_new()?; - let memory_manager = MemoryManager::new(fd.clone(), &config.lock().unwrap().memory.clone()) - .map_err(Error::MemoryManager)?; + let memory_manager = + MemoryManager::new(fd.clone(), &config.lock().unwrap().memory.clone(), None) + .map_err(Error::MemoryManager)?; Vm::new_from_memory_manager( config,