Skip to content

Commit 5089fcc

Browse files
committed
fix(vmm): only use memfd if no vhost-user-blk devices configured
Page faults are more expensive for shared memory mapping (like memfd). For this reason, we only back guest memory with a memfd if a vhost-user-blk device is configured in the VM, otherwise we fall back to anonymous private memory. This is recovering performance demonstrated before commit 027a992 had been merged. The vhost-user-blk branch in VM creation is not currently covered by Rust integration tests, because we are looking for a converging solution, so guest memory is always created in the same way, and implementing required integration test infrastructure code (spawing a backend process) would not be useful long term. (cherry picked from commit 931207b) Signed-off-by: Nikita Kalyazin <[email protected]>
1 parent 36184b4 commit 5089fcc

File tree

1 file changed

+33
-6
lines changed

1 file changed

+33
-6
lines changed

src/vmm/src/builder.rs

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -237,12 +237,39 @@ pub fn build_microvm_for_boot(
237237
.ok_or(MissingKernelConfig)?;
238238

239239
let track_dirty_pages = vm_resources.track_dirty_pages();
240-
let guest_memory = GuestMemoryMmap::memfd_backed(
241-
vm_resources.vm_config.mem_size_mib,
242-
track_dirty_pages,
243-
vm_resources.vm_config.huge_pages,
244-
)
245-
.map_err(StartMicrovmError::GuestMemory)?;
240+
241+
let vhost_user_device_used = vm_resources
242+
.block
243+
.devices
244+
.iter()
245+
.any(|b| b.lock().expect("Poisoned lock").is_vhost_user());
246+
247+
// Page faults are more expensive for shared memory mapping, including memfd.
248+
// For this reason, we only back guest memory with a memfd
249+
// if a vhost-user-blk device is configured in the VM, otherwise we fall back to
250+
// an anonymous private memory.
251+
//
252+
// The vhost-user-blk branch is not currently covered by integration tests in Rust,
253+
// because that would require running a backend process. If in the future we converge to
254+
// a single way of backing guest memory for vhost-user and non-vhost-user cases,
255+
// that would not be worth the effort.
256+
let guest_memory = if vhost_user_device_used {
257+
GuestMemoryMmap::memfd_backed(
258+
vm_resources.vm_config.mem_size_mib,
259+
track_dirty_pages,
260+
vm_resources.vm_config.huge_pages,
261+
)
262+
.map_err(StartMicrovmError::GuestMemory)?
263+
} else {
264+
let regions = crate::arch::arch_memory_regions(vm_resources.vm_config.mem_size_mib << 20);
265+
GuestMemoryMmap::from_raw_regions(
266+
&regions,
267+
track_dirty_pages,
268+
vm_resources.vm_config.huge_pages,
269+
)
270+
.map_err(StartMicrovmError::GuestMemory)?
271+
};
272+
246273
let entry_addr = load_kernel(boot_config, &guest_memory)?;
247274
let initrd = load_initrd_from_config(boot_config, &guest_memory)?;
248275
// Clone the command-line so that a failed boot doesn't pollute the original.

0 commit comments

Comments
 (0)