Skip to content

Commit c852830

Browse files
committed
refactor: Extract guest memory allocation into function
Move guest memory allocation into a function of `VmResources`. The configuration we end up allocating depends solely on the information in `VmResources`, and this allows us to easily use production guest memory configurations in benchmarks. Signed-off-by: Patrick Roy <[email protected]>
1 parent 5ac5d47 commit c852830

File tree

2 files changed

+41
-32
lines changed

2 files changed

+41
-32
lines changed

src/vmm/src/builder.rs

Lines changed: 4 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ use crate::utils::u64_to_usize;
6464
use crate::vmm_config::boot_source::BootConfig;
6565
use crate::vmm_config::instance_info::InstanceInfo;
6666
use crate::vmm_config::machine_config::{VmConfig, VmConfigError};
67-
use crate::vstate::memory::{GuestAddress, GuestMemory, GuestMemoryExtension, GuestMemoryMmap};
67+
use crate::vstate::memory::{GuestAddress, GuestMemory, GuestMemoryMmap};
6868
use crate::vstate::vcpu::{Vcpu, VcpuConfig, VcpuError};
6969
use crate::vstate::vm::Vm;
7070
use crate::{device_manager, EventManager, Vmm, VmmError};
@@ -252,37 +252,9 @@ pub fn build_microvm_for_boot(
252252
.boot_source_builder()
253253
.ok_or(MissingKernelConfig)?;
254254

255-
let vhost_user_device_used = vm_resources
256-
.block
257-
.devices
258-
.iter()
259-
.any(|b| b.lock().expect("Poisoned lock").is_vhost_user());
260-
261-
// Page faults are more expensive for shared memory mapping, including memfd.
262-
// For this reason, we only back guest memory with a memfd
263-
// if a vhost-user-blk device is configured in the VM, otherwise we fall back to
264-
// an anonymous private memory.
265-
//
266-
// The vhost-user-blk branch is not currently covered by integration tests in Rust,
267-
// because that would require running a backend process. If in the future we converge to
268-
// a single way of backing guest memory for vhost-user and non-vhost-user cases,
269-
// that would not be worth the effort.
270-
let guest_memory = if vhost_user_device_used {
271-
GuestMemoryMmap::memfd_backed(
272-
vm_resources.vm_config.mem_size_mib,
273-
vm_resources.vm_config.track_dirty_pages,
274-
vm_resources.vm_config.huge_pages,
275-
)
276-
.map_err(StartMicrovmError::GuestMemory)?
277-
} else {
278-
let regions = crate::arch::arch_memory_regions(vm_resources.vm_config.mem_size_mib << 20);
279-
GuestMemoryMmap::from_raw_regions(
280-
&regions,
281-
vm_resources.vm_config.track_dirty_pages,
282-
vm_resources.vm_config.huge_pages,
283-
)
284-
.map_err(StartMicrovmError::GuestMemory)?
285-
};
255+
let guest_memory = vm_resources
256+
.allocate_guest_memory()
257+
.map_err(StartMicrovmError::GuestMemory)?;
286258

287259
let entry_addr = load_kernel(boot_config, &guest_memory)?;
288260
let initrd = load_initrd_from_config(boot_config, &guest_memory)?;

src/vmm/src/resources.rs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ use crate::vmm_config::metrics::{init_metrics, MetricsConfig, MetricsConfigError
2828
use crate::vmm_config::mmds::{MmdsConfig, MmdsConfigError};
2929
use crate::vmm_config::net::*;
3030
use crate::vmm_config::vsock::*;
31+
use crate::vstate::memory::{GuestMemoryExtension, GuestMemoryMmap, MemoryError};
3132

3233
/// Errors encountered when configuring microVM resources.
3334
#[derive(Debug, thiserror::Error, displaydoc::Display)]
@@ -468,6 +469,42 @@ impl VmResources {
468469

469470
Ok(())
470471
}
472+
473+
/// Allocates guest memory in a configuration most appropriate for these [`VmResources`].
474+
///
475+
/// If vhost-user-blk devices are in use, allocates memfd-backed shared memory, otherwise
476+
/// prefers anonymous memory for performance reasons.
477+
pub fn allocate_guest_memory(&self) -> Result<GuestMemoryMmap, MemoryError> {
478+
let vhost_user_device_used = self
479+
.block
480+
.devices
481+
.iter()
482+
.any(|b| b.lock().expect("Poisoned lock").is_vhost_user());
483+
484+
// Page faults are more expensive for shared memory mapping, including memfd.
485+
// For this reason, we only back guest memory with a memfd
486+
// if a vhost-user-blk device is configured in the VM, otherwise we fall back to
487+
// an anonymous private memory.
488+
//
489+
// The vhost-user-blk branch is not currently covered by integration tests in Rust,
490+
// because that would require running a backend process. If in the future we converge to
491+
// a single way of backing guest memory for vhost-user and non-vhost-user cases,
492+
// that would not be worth the effort.
493+
if vhost_user_device_used {
494+
GuestMemoryMmap::memfd_backed(
495+
self.vm_config.mem_size_mib,
496+
self.vm_config.track_dirty_pages,
497+
self.vm_config.huge_pages,
498+
)
499+
} else {
500+
let regions = crate::arch::arch_memory_regions(self.vm_config.mem_size_mib << 20);
501+
GuestMemoryMmap::from_raw_regions(
502+
&regions,
503+
self.vm_config.track_dirty_pages,
504+
self.vm_config.huge_pages,
505+
)
506+
}
507+
}
471508
}
472509

473510
impl From<&VmResources> for VmmConfig {

0 commit comments

Comments
 (0)