diff --git a/src/runtime-rs/config/configuration-cloud-hypervisor.toml.in b/src/runtime-rs/config/configuration-cloud-hypervisor.toml.in index 7eac48c100..daa86edf01 100644 --- a/src/runtime-rs/config/configuration-cloud-hypervisor.toml.in +++ b/src/runtime-rs/config/configuration-cloud-hypervisor.toml.in @@ -177,6 +177,15 @@ block_device_driver = "virtio-blk-pci" # Default false #block_device_cache_direct = true +# Enable pre allocation of VM RAM, default false +# Enabling this will result in lower container density +# as all of the memory will be allocated and locked +# This is useful when you want to reserve all the memory +# upfront or in the cases where you want memory latencies +# to be very predictable +# Default false +#enable_mem_prealloc = true + # Enable huge pages for VM RAM, default false # Enabling this will result in the VM memory # being allocated using huge pages. diff --git a/src/runtime-rs/crates/hypervisor/ch-config/src/convert.rs b/src/runtime-rs/crates/hypervisor/ch-config/src/convert.rs index 09443323c5..09c14d7b67 100644 --- a/src/runtime-rs/crates/hypervisor/ch-config/src/convert.rs +++ b/src/runtime-rs/crates/hypervisor/ch-config/src/convert.rs @@ -285,6 +285,8 @@ impl TryFrom<(MemoryInfo, GuestProtection)> for MemoryConfig { hotplug_size, + prefault: mem.enable_mem_prealloc, + ..Default::default() }; diff --git a/src/runtime-rs/crates/hypervisor/src/qemu/cmdline_generator.rs b/src/runtime-rs/crates/hypervisor/src/qemu/cmdline_generator.rs index 41475a3bbe..338fd8d074 100644 --- a/src/runtime-rs/crates/hypervisor/src/qemu/cmdline_generator.rs +++ b/src/runtime-rs/crates/hypervisor/src/qemu/cmdline_generator.rs @@ -625,6 +625,7 @@ struct MemoryBackendFile { size: u64, share: bool, readonly: bool, + prealloc: bool, } impl MemoryBackendFile { @@ -635,6 +636,7 @@ impl MemoryBackendFile { size, share: false, readonly: false, + prealloc: false, } } @@ -647,6 +649,11 @@ impl MemoryBackendFile { self.readonly = readonly; self } + + fn set_prealloc(&mut self, prealloc: bool) -> &mut Self { + self.prealloc = prealloc; + self + } } #[async_trait] @@ -658,6 +665,10 @@ impl ToQemuParams for MemoryBackendFile { params.push(format!("mem-path={}", self.mem_path)); params.push(format!("size={}", format_memory(self.size))); params.push(format!("share={}", if self.share { "on" } else { "off" })); + params.push(format!( + "prealloc={}", + if self.prealloc { "on" } else { "off" } + )); params.push(format!( "readonly={}", if self.readonly { "on" } else { "off" } @@ -2261,6 +2272,10 @@ impl<'a> QemuCmdLine<'a> { MemoryBackendFile::new("entire-guest-memory-share", "/dev/shm", self.memory.size); mem_file.set_share(true); + if self.config.memory_info.enable_mem_prealloc { + mem_file.set_prealloc(true); + } + // don't put the /dev/shm memory backend file into the anonymous container, // there has to be at most one of those so keep it by name in Memory instead //self.devices.push(Box::new(mem_file));