diff --git a/fuzz/fuzz_targets/mem.rs b/fuzz/fuzz_targets/mem.rs index 6d7bc6b92..ad91e1e33 100644 --- a/fuzz/fuzz_targets/mem.rs +++ b/fuzz/fuzz_targets/mem.rs @@ -137,6 +137,7 @@ fn create_dummy_virtio_mem(bytes: &[u8; VIRTIO_MEM_DATA_SIZE]) -> (Mem, Arc,\ hotplugged_size=,\ - prefault=on|off\"", + prefault=on|off,thp=on|off\"", ) .default_value(default_memory) .group("vm-config"), @@ -676,6 +676,7 @@ mod unit_tests { hugepage_size: None, prefault: false, zones: None, + thp: true, }, payload: Some(PayloadConfig { kernel: Some(PathBuf::from("/path/to/kernel")), diff --git a/vmm/src/config.rs b/vmm/src/config.rs index 43c1faec6..45623308b 100644 --- a/vmm/src/config.rs +++ b/vmm/src/config.rs @@ -658,7 +658,8 @@ impl MemoryConfig { .add("shared") .add("hugepages") .add("hugepage_size") - .add("prefault"); + .add("prefault") + .add("thp"); parser.parse(memory).map_err(Error::ParseMemory)?; let size = parser @@ -702,6 +703,11 @@ impl MemoryConfig { .map_err(Error::ParseMemory)? .unwrap_or(Toggle(false)) .0; + let thp = parser + .convert::("thp") + .map_err(Error::ParseMemory)? + .unwrap_or(Toggle(true)) + .0; let zones: Option> = if let Some(memory_zones) = &memory_zones { let mut zones = Vec::new(); @@ -788,6 +794,7 @@ impl MemoryConfig { hugepage_size, prefault, zones, + thp, }) } @@ -2727,6 +2734,7 @@ mod tests { hugepage_size: None, prefault: false, zones: None, + thp: true, }, payload: Some(PayloadConfig { kernel: Some(PathBuf::from("/path/to/kernel")), diff --git a/vmm/src/lib.rs b/vmm/src/lib.rs index 0b7224942..89c3163aa 100644 --- a/vmm/src/lib.rs +++ b/vmm/src/lib.rs @@ -2062,6 +2062,7 @@ mod unit_tests { hugepage_size: None, prefault: false, zones: None, + thp: true, }, payload: Some(PayloadConfig { kernel: Some(PathBuf::from("/path/to/kernel")), diff --git a/vmm/src/memory_manager.rs b/vmm/src/memory_manager.rs index 24a9edcf5..c814ff33f 100644 --- a/vmm/src/memory_manager.rs +++ b/vmm/src/memory_manager.rs @@ -175,6 +175,7 @@ pub struct MemoryManager { hugepages: bool, hugepage_size: Option, prefault: bool, + thp: bool, #[cfg(target_arch = "x86_64")] sgx_epc_region: Option, user_provided_zones: bool, @@ -442,6 +443,7 @@ impl MemoryManager { ram_regions: &[(GuestAddress, usize)], zones: &[MemoryZoneConfig], prefault: Option, + thp: bool, ) -> Result<(Vec>, MemoryZones), Error> { let mut zones = zones.to_owned(); let mut mem_regions = Vec::new(); @@ -498,6 +500,7 @@ impl MemoryManager { zone.hugepage_size, zone.host_numa_node, None, + thp, )?; // Add region to the list of regions associated with the @@ -550,6 +553,7 @@ impl MemoryManager { zones_config: &[MemoryZoneConfig], prefault: Option, mut existing_memory_files: HashMap, + thp: bool, ) -> Result<(Vec>, MemoryZones), Error> { let mut memory_regions = Vec::new(); let mut memory_zones = HashMap::new(); @@ -575,6 +579,7 @@ impl MemoryManager { zone_config.hugepage_size, zone_config.host_numa_node, existing_memory_files.remove(&guest_ram_mapping.slot), + thp, )?; memory_regions.push(Arc::clone(®ion)); if let Some(memory_zone) = memory_zones.get_mut(&guest_ram_mapping.zone_id) { @@ -911,6 +916,7 @@ impl MemoryManager { &zones, prefault, existing_memory_files.unwrap_or_default(), + config.thp, )?; let guest_memory = GuestMemoryMmap::from_arc_regions(regions).map_err(Error::GuestMemory)?; @@ -948,7 +954,7 @@ impl MemoryManager { .collect(); let (mem_regions, mut memory_zones) = - Self::create_memory_regions_from_zones(&ram_regions, &zones, prefault)?; + Self::create_memory_regions_from_zones(&ram_regions, &zones, prefault, config.thp)?; let mut guest_memory = GuestMemoryMmap::from_arc_regions(mem_regions).map_err(Error::GuestMemory)?; @@ -997,6 +1003,7 @@ impl MemoryManager { zone.hugepage_size, zone.host_numa_node, None, + config.thp, )?; guest_memory = guest_memory @@ -1125,6 +1132,7 @@ impl MemoryManager { dynamic, #[cfg(target_arch = "aarch64")] uefi_flash: None, + thp: config.thp, }; memory_manager.allocate_address_space()?; @@ -1298,6 +1306,7 @@ impl MemoryManager { hugepage_size: Option, host_numa_node: Option, existing_memory_file: Option, + thp: bool, ) -> Result, Error> { let mut mmap_flags = libc::MAP_NORESERVE; @@ -1336,7 +1345,7 @@ impl MemoryManager { ) .map_err(Error::GuestMemory)?; - if region.file_offset().is_none() { + if region.file_offset().is_none() && thp { info!( "Anonymous mapping at 0x{:x} (size = 0x{:x})", region.as_ptr() as u64, @@ -1438,6 +1447,7 @@ impl MemoryManager { self.hugepage_size, None, None, + self.thp, )?; // Map it into the guest diff --git a/vmm/src/vm_config.rs b/vmm/src/vm_config.rs index e52c58eae..0d611d5f7 100644 --- a/vmm/src/vm_config.rs +++ b/vmm/src/vm_config.rs @@ -139,6 +139,10 @@ impl Default for HotplugMethod { } } +fn default_memoryconfig_thp() -> bool { + true +} + #[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)] pub struct MemoryConfig { pub size: u64, @@ -160,6 +164,8 @@ pub struct MemoryConfig { pub prefault: bool, #[serde(default)] pub zones: Option>, + #[serde(default = "default_memoryconfig_thp")] + pub thp: bool, } pub const DEFAULT_MEMORY_MB: u64 = 512; @@ -177,6 +183,7 @@ impl Default for MemoryConfig { hugepage_size: None, prefault: false, zones: None, + thp: true, } } }