mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2024-11-04 19:11:11 +00:00
vmm: add prefault option in memory and memory-zone
The argument `prefault` is provided in MemoryManager, but it can only be used by SGX and restore. With prefault (MAP_POPULATE) been set, subsequent page faults will decrease during running, although it will make boot slower. This commit adds `prefault` in MemoryConfig and MemoryZoneConfig. To resolve conflict between memory and restore, argument `prefault` has been changed from `bool` to `Option<bool>`, when its value is None, config from memory will be used, otherwise argument in Option will be used. Signed-off-by: Yu Li <liyu.yukiteru@bytedance.com>
This commit is contained in:
parent
90d79fa76b
commit
08021087ec
@ -163,7 +163,8 @@ fn create_app<'a, 'b>(
|
||||
hugepages=on|off,hugepage_size=<hugepage_size>,\
|
||||
hotplug_method=acpi|virtio-mem,\
|
||||
hotplug_size=<hotpluggable_memory_size>,\
|
||||
hotplugged_size=<hotplugged_memory_size>\"",
|
||||
hotplugged_size=<hotplugged_memory_size>,\
|
||||
prefault=on|off\"",
|
||||
)
|
||||
.default_value(default_memory)
|
||||
.group("vm-config"),
|
||||
@ -178,7 +179,8 @@ fn create_app<'a, 'b>(
|
||||
hugepages=on|off,hugepage_size=<hugepage_size>,\
|
||||
host_numa_node=<node_id>,\
|
||||
id=<zone_identifier>,hotplug_size=<hotpluggable_memory_size>,\
|
||||
hotplugged_size=<hotplugged_memory_size>\"",
|
||||
hotplugged_size=<hotplugged_memory_size>,\
|
||||
prefault=on|off\"",
|
||||
)
|
||||
.takes_value(true)
|
||||
.min_values(1)
|
||||
@ -644,8 +646,9 @@ mod unit_tests {
|
||||
hotplugged_size: None,
|
||||
shared: false,
|
||||
hugepages: false,
|
||||
zones: None,
|
||||
hugepage_size: None,
|
||||
prefault: false,
|
||||
zones: None,
|
||||
},
|
||||
kernel: Some(KernelConfig {
|
||||
path: PathBuf::from("/path/to/kernel"),
|
||||
|
@ -546,6 +546,9 @@ components:
|
||||
hotplugged_size:
|
||||
type: integer
|
||||
format: int64
|
||||
prefault:
|
||||
type: boolean
|
||||
default: false
|
||||
|
||||
MemoryConfig:
|
||||
required:
|
||||
@ -577,6 +580,9 @@ components:
|
||||
hugepage_size:
|
||||
type: integer
|
||||
format: int64
|
||||
prefault:
|
||||
type: boolean
|
||||
default: false
|
||||
zones:
|
||||
type: array
|
||||
items:
|
||||
|
@ -491,6 +491,8 @@ pub struct MemoryZoneConfig {
|
||||
pub hotplug_size: Option<u64>,
|
||||
#[serde(default)]
|
||||
pub hotplugged_size: Option<u64>,
|
||||
#[serde(default)]
|
||||
pub prefault: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
|
||||
@ -511,6 +513,8 @@ pub struct MemoryConfig {
|
||||
#[serde(default)]
|
||||
pub hugepage_size: Option<u64>,
|
||||
#[serde(default)]
|
||||
pub prefault: bool,
|
||||
#[serde(default)]
|
||||
pub zones: Option<Vec<MemoryZoneConfig>>,
|
||||
}
|
||||
|
||||
@ -526,7 +530,8 @@ impl MemoryConfig {
|
||||
.add("hotplugged_size")
|
||||
.add("shared")
|
||||
.add("hugepages")
|
||||
.add("hugepage_size");
|
||||
.add("hugepage_size")
|
||||
.add("prefault");
|
||||
parser.parse(memory).map_err(Error::ParseMemory)?;
|
||||
|
||||
let size = parser
|
||||
@ -565,6 +570,11 @@ impl MemoryConfig {
|
||||
.convert::<ByteSized>("hugepage_size")
|
||||
.map_err(Error::ParseMemory)?
|
||||
.map(|v| v.0);
|
||||
let prefault = parser
|
||||
.convert::<Toggle>("prefault")
|
||||
.map_err(Error::ParseMemory)?
|
||||
.unwrap_or(Toggle(false))
|
||||
.0;
|
||||
|
||||
let zones: Option<Vec<MemoryZoneConfig>> = if let Some(memory_zones) = &memory_zones {
|
||||
let mut zones = Vec::new();
|
||||
@ -579,7 +589,8 @@ impl MemoryConfig {
|
||||
.add("hugepage_size")
|
||||
.add("host_numa_node")
|
||||
.add("hotplug_size")
|
||||
.add("hotplugged_size");
|
||||
.add("hotplugged_size")
|
||||
.add("prefault");
|
||||
parser.parse(memory_zone).map_err(Error::ParseMemoryZone)?;
|
||||
|
||||
let id = parser.get("id").ok_or(Error::ParseMemoryZoneIdMissing)?;
|
||||
@ -615,6 +626,11 @@ impl MemoryConfig {
|
||||
.convert::<ByteSized>("hotplugged_size")
|
||||
.map_err(Error::ParseMemoryZone)?
|
||||
.map(|v| v.0);
|
||||
let prefault = parser
|
||||
.convert::<Toggle>("prefault")
|
||||
.map_err(Error::ParseMemoryZone)?
|
||||
.unwrap_or(Toggle(false))
|
||||
.0;
|
||||
|
||||
zones.push(MemoryZoneConfig {
|
||||
id,
|
||||
@ -626,6 +642,7 @@ impl MemoryConfig {
|
||||
host_numa_node,
|
||||
hotplug_size,
|
||||
hotplugged_size,
|
||||
prefault,
|
||||
});
|
||||
}
|
||||
Some(zones)
|
||||
@ -642,6 +659,7 @@ impl MemoryConfig {
|
||||
shared,
|
||||
hugepages,
|
||||
hugepage_size,
|
||||
prefault,
|
||||
zones,
|
||||
})
|
||||
}
|
||||
@ -676,6 +694,7 @@ impl Default for MemoryConfig {
|
||||
shared: false,
|
||||
hugepages: false,
|
||||
hugepage_size: None,
|
||||
prefault: false,
|
||||
zones: None,
|
||||
}
|
||||
}
|
||||
@ -2678,6 +2697,7 @@ mod tests {
|
||||
shared: false,
|
||||
hugepages: false,
|
||||
hugepage_size: None,
|
||||
prefault: false,
|
||||
zones: None,
|
||||
},
|
||||
kernel: Some(KernelConfig {
|
||||
|
@ -144,6 +144,7 @@ pub struct MemoryManager {
|
||||
shared: bool,
|
||||
hugepages: bool,
|
||||
hugepage_size: Option<u64>,
|
||||
prefault: bool,
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
sgx_epc_region: Option<SgxEpcRegion>,
|
||||
user_provided_zones: bool,
|
||||
@ -399,7 +400,7 @@ impl MemoryManager {
|
||||
fn create_memory_regions_from_zones(
|
||||
ram_regions: &[(GuestAddress, usize)],
|
||||
zones: &[MemoryZoneConfig],
|
||||
prefault: bool,
|
||||
prefault: Option<bool>,
|
||||
) -> Result<(Vec<Arc<GuestRegionMmap>>, MemoryZones), Error> {
|
||||
let mut zones = zones.to_owned();
|
||||
let mut mem_regions = Vec::new();
|
||||
@ -447,7 +448,10 @@ impl MemoryManager {
|
||||
file_offset,
|
||||
region_start,
|
||||
region_size,
|
||||
prefault,
|
||||
match prefault {
|
||||
Some(pf) => pf,
|
||||
None => zone.prefault,
|
||||
},
|
||||
zone.shared,
|
||||
zone.hugepages,
|
||||
zone.hugepage_size,
|
||||
@ -543,7 +547,7 @@ impl MemoryManager {
|
||||
pub fn new(
|
||||
vm: Arc<dyn hypervisor::Vm>,
|
||||
config: &MemoryConfig,
|
||||
prefault: bool,
|
||||
prefault: Option<bool>,
|
||||
phys_bits: u8,
|
||||
#[cfg(feature = "tdx")] tdx_enabled: bool,
|
||||
) -> Result<Arc<Mutex<MemoryManager>>, Error> {
|
||||
@ -601,6 +605,7 @@ impl MemoryManager {
|
||||
host_numa_node: None,
|
||||
hotplug_size: config.hotplug_size,
|
||||
hotplugged_size: config.hotplugged_size,
|
||||
prefault: config.prefault,
|
||||
}];
|
||||
|
||||
(config.size, zones)
|
||||
@ -716,12 +721,18 @@ impl MemoryManager {
|
||||
* virtio_devices::VIRTIO_MEM_ALIGN_SIZE,
|
||||
);
|
||||
|
||||
// When `prefault` is set by vm_restore, memory manager
|
||||
// will create ram region with `prefault` option in
|
||||
// restore config rather than same option in zone
|
||||
let region = MemoryManager::create_ram_region(
|
||||
&None,
|
||||
0,
|
||||
start_addr,
|
||||
hotplug_size as usize,
|
||||
false,
|
||||
match prefault {
|
||||
Some(pf) => pf,
|
||||
None => zone.prefault,
|
||||
},
|
||||
zone.shared,
|
||||
zone.hugepages,
|
||||
zone.hugepage_size,
|
||||
@ -810,6 +821,7 @@ impl MemoryManager {
|
||||
shared: config.shared,
|
||||
hugepages: config.hugepages,
|
||||
hugepage_size: config.hugepage_size,
|
||||
prefault: config.prefault,
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
sgx_epc_region: None,
|
||||
user_provided_zones,
|
||||
@ -883,7 +895,7 @@ impl MemoryManager {
|
||||
let mm = MemoryManager::new(
|
||||
vm,
|
||||
config,
|
||||
prefault,
|
||||
Some(prefault),
|
||||
phys_bits,
|
||||
#[cfg(feature = "tdx")]
|
||||
false,
|
||||
@ -1123,7 +1135,7 @@ impl MemoryManager {
|
||||
0,
|
||||
start_addr,
|
||||
size,
|
||||
false,
|
||||
self.prefault,
|
||||
self.shared,
|
||||
self.hugepages,
|
||||
self.hugepage_size,
|
||||
|
@ -762,7 +762,7 @@ impl Vm {
|
||||
let memory_manager = MemoryManager::new(
|
||||
vm.clone(),
|
||||
&config.lock().unwrap().memory.clone(),
|
||||
false,
|
||||
None,
|
||||
phys_bits,
|
||||
#[cfg(feature = "tdx")]
|
||||
tdx_enabled,
|
||||
@ -886,7 +886,7 @@ impl Vm {
|
||||
let memory_manager = MemoryManager::new(
|
||||
vm.clone(),
|
||||
&config.lock().unwrap().memory.clone(),
|
||||
false,
|
||||
None,
|
||||
phys_bits,
|
||||
#[cfg(feature = "tdx")]
|
||||
false,
|
||||
|
Loading…
Reference in New Issue
Block a user