From 7839e121f6426e35ffc72a84ab7dd418c0c8b015 Mon Sep 17 00:00:00 2001 From: Bo Chen Date: Tue, 25 May 2021 13:34:49 -0700 Subject: [PATCH] vmm: Add dirty pages tracked by vm_memory::bitmap to live migration Live migration currently handles guest memory writes from the guest through the KVM dirty page tracking and sends those dirty pages to the destination. This patch augments the live migration support with dirty page tracking of writes from the VMM to the guest memory(e.g. virtio devices). Fixes: #2458 Signed-off-by: Bo Chen --- vmm/src/memory_manager.rs | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/vmm/src/memory_manager.rs b/vmm/src/memory_manager.rs index 0ff58dc35..8ce8c01dd 100644 --- a/vmm/src/memory_manager.rs +++ b/vmm/src/memory_manager.rs @@ -1477,9 +1477,29 @@ impl MemoryManager { let page_size = 4096; // TODO: Does this need to vary? let mut table = MemoryRangeTable::default(); for r in &self.guest_ram_mappings { - let dirty_bitmap = self.vm.get_dirty_log(r.slot, r.size).map_err(|e| { + let vm_dirty_bitmap = self.vm.get_dirty_log(r.slot, r.size).map_err(|e| { MigratableError::MigrateSend(anyhow!("Error getting VM dirty log {}", e)) })?; + let vmm_dirty_bitmap = match self.guest_memory.memory().find_region(GuestAddress(r.gpa)) + { + Some(region) => { + assert!(region.start_addr().raw_value() == r.gpa); + assert!(region.len() == r.size); + region.bitmap().get_and_reset() + } + None => { + return Err(MigratableError::MigrateSend(anyhow!( + "Error finding 'guest memory region' with address {:x}", + r.gpa + ))) + } + }; + + let dirty_bitmap: Vec = vm_dirty_bitmap + .iter() + .zip(vmm_dirty_bitmap.iter()) + .map(|(x, y)| x | y) + .collect(); let mut entry: Option = None; for (i, block) in dirty_bitmap.iter().enumerate() { @@ -1525,6 +1545,11 @@ impl MemoryManager { MigratableError::MigrateSend(anyhow!("Error getting VM dirty log {}", e)) })?; } + + for r in self.guest_memory.memory().iter() { + r.bitmap().reset(); + } + Ok(()) } }