mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2024-10-01 11:05:46 +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>,\
|
hugepages=on|off,hugepage_size=<hugepage_size>,\
|
||||||
hotplug_method=acpi|virtio-mem,\
|
hotplug_method=acpi|virtio-mem,\
|
||||||
hotplug_size=<hotpluggable_memory_size>,\
|
hotplug_size=<hotpluggable_memory_size>,\
|
||||||
hotplugged_size=<hotplugged_memory_size>\"",
|
hotplugged_size=<hotplugged_memory_size>,\
|
||||||
|
prefault=on|off\"",
|
||||||
)
|
)
|
||||||
.default_value(default_memory)
|
.default_value(default_memory)
|
||||||
.group("vm-config"),
|
.group("vm-config"),
|
||||||
@ -178,7 +179,8 @@ fn create_app<'a, 'b>(
|
|||||||
hugepages=on|off,hugepage_size=<hugepage_size>,\
|
hugepages=on|off,hugepage_size=<hugepage_size>,\
|
||||||
host_numa_node=<node_id>,\
|
host_numa_node=<node_id>,\
|
||||||
id=<zone_identifier>,hotplug_size=<hotpluggable_memory_size>,\
|
id=<zone_identifier>,hotplug_size=<hotpluggable_memory_size>,\
|
||||||
hotplugged_size=<hotplugged_memory_size>\"",
|
hotplugged_size=<hotplugged_memory_size>,\
|
||||||
|
prefault=on|off\"",
|
||||||
)
|
)
|
||||||
.takes_value(true)
|
.takes_value(true)
|
||||||
.min_values(1)
|
.min_values(1)
|
||||||
@ -644,8 +646,9 @@ mod unit_tests {
|
|||||||
hotplugged_size: None,
|
hotplugged_size: None,
|
||||||
shared: false,
|
shared: false,
|
||||||
hugepages: false,
|
hugepages: false,
|
||||||
zones: None,
|
|
||||||
hugepage_size: None,
|
hugepage_size: None,
|
||||||
|
prefault: false,
|
||||||
|
zones: None,
|
||||||
},
|
},
|
||||||
kernel: Some(KernelConfig {
|
kernel: Some(KernelConfig {
|
||||||
path: PathBuf::from("/path/to/kernel"),
|
path: PathBuf::from("/path/to/kernel"),
|
||||||
|
@ -546,6 +546,9 @@ components:
|
|||||||
hotplugged_size:
|
hotplugged_size:
|
||||||
type: integer
|
type: integer
|
||||||
format: int64
|
format: int64
|
||||||
|
prefault:
|
||||||
|
type: boolean
|
||||||
|
default: false
|
||||||
|
|
||||||
MemoryConfig:
|
MemoryConfig:
|
||||||
required:
|
required:
|
||||||
@ -577,6 +580,9 @@ components:
|
|||||||
hugepage_size:
|
hugepage_size:
|
||||||
type: integer
|
type: integer
|
||||||
format: int64
|
format: int64
|
||||||
|
prefault:
|
||||||
|
type: boolean
|
||||||
|
default: false
|
||||||
zones:
|
zones:
|
||||||
type: array
|
type: array
|
||||||
items:
|
items:
|
||||||
|
@ -491,6 +491,8 @@ pub struct MemoryZoneConfig {
|
|||||||
pub hotplug_size: Option<u64>,
|
pub hotplug_size: Option<u64>,
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub hotplugged_size: Option<u64>,
|
pub hotplugged_size: Option<u64>,
|
||||||
|
#[serde(default)]
|
||||||
|
pub prefault: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
|
#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
|
||||||
@ -511,6 +513,8 @@ pub struct MemoryConfig {
|
|||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub hugepage_size: Option<u64>,
|
pub hugepage_size: Option<u64>,
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
|
pub prefault: bool,
|
||||||
|
#[serde(default)]
|
||||||
pub zones: Option<Vec<MemoryZoneConfig>>,
|
pub zones: Option<Vec<MemoryZoneConfig>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -526,7 +530,8 @@ impl MemoryConfig {
|
|||||||
.add("hotplugged_size")
|
.add("hotplugged_size")
|
||||||
.add("shared")
|
.add("shared")
|
||||||
.add("hugepages")
|
.add("hugepages")
|
||||||
.add("hugepage_size");
|
.add("hugepage_size")
|
||||||
|
.add("prefault");
|
||||||
parser.parse(memory).map_err(Error::ParseMemory)?;
|
parser.parse(memory).map_err(Error::ParseMemory)?;
|
||||||
|
|
||||||
let size = parser
|
let size = parser
|
||||||
@ -565,6 +570,11 @@ impl MemoryConfig {
|
|||||||
.convert::<ByteSized>("hugepage_size")
|
.convert::<ByteSized>("hugepage_size")
|
||||||
.map_err(Error::ParseMemory)?
|
.map_err(Error::ParseMemory)?
|
||||||
.map(|v| v.0);
|
.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 zones: Option<Vec<MemoryZoneConfig>> = if let Some(memory_zones) = &memory_zones {
|
||||||
let mut zones = Vec::new();
|
let mut zones = Vec::new();
|
||||||
@ -579,7 +589,8 @@ impl MemoryConfig {
|
|||||||
.add("hugepage_size")
|
.add("hugepage_size")
|
||||||
.add("host_numa_node")
|
.add("host_numa_node")
|
||||||
.add("hotplug_size")
|
.add("hotplug_size")
|
||||||
.add("hotplugged_size");
|
.add("hotplugged_size")
|
||||||
|
.add("prefault");
|
||||||
parser.parse(memory_zone).map_err(Error::ParseMemoryZone)?;
|
parser.parse(memory_zone).map_err(Error::ParseMemoryZone)?;
|
||||||
|
|
||||||
let id = parser.get("id").ok_or(Error::ParseMemoryZoneIdMissing)?;
|
let id = parser.get("id").ok_or(Error::ParseMemoryZoneIdMissing)?;
|
||||||
@ -615,6 +626,11 @@ impl MemoryConfig {
|
|||||||
.convert::<ByteSized>("hotplugged_size")
|
.convert::<ByteSized>("hotplugged_size")
|
||||||
.map_err(Error::ParseMemoryZone)?
|
.map_err(Error::ParseMemoryZone)?
|
||||||
.map(|v| v.0);
|
.map(|v| v.0);
|
||||||
|
let prefault = parser
|
||||||
|
.convert::<Toggle>("prefault")
|
||||||
|
.map_err(Error::ParseMemoryZone)?
|
||||||
|
.unwrap_or(Toggle(false))
|
||||||
|
.0;
|
||||||
|
|
||||||
zones.push(MemoryZoneConfig {
|
zones.push(MemoryZoneConfig {
|
||||||
id,
|
id,
|
||||||
@ -626,6 +642,7 @@ impl MemoryConfig {
|
|||||||
host_numa_node,
|
host_numa_node,
|
||||||
hotplug_size,
|
hotplug_size,
|
||||||
hotplugged_size,
|
hotplugged_size,
|
||||||
|
prefault,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
Some(zones)
|
Some(zones)
|
||||||
@ -642,6 +659,7 @@ impl MemoryConfig {
|
|||||||
shared,
|
shared,
|
||||||
hugepages,
|
hugepages,
|
||||||
hugepage_size,
|
hugepage_size,
|
||||||
|
prefault,
|
||||||
zones,
|
zones,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -676,6 +694,7 @@ impl Default for MemoryConfig {
|
|||||||
shared: false,
|
shared: false,
|
||||||
hugepages: false,
|
hugepages: false,
|
||||||
hugepage_size: None,
|
hugepage_size: None,
|
||||||
|
prefault: false,
|
||||||
zones: None,
|
zones: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2678,6 +2697,7 @@ mod tests {
|
|||||||
shared: false,
|
shared: false,
|
||||||
hugepages: false,
|
hugepages: false,
|
||||||
hugepage_size: None,
|
hugepage_size: None,
|
||||||
|
prefault: false,
|
||||||
zones: None,
|
zones: None,
|
||||||
},
|
},
|
||||||
kernel: Some(KernelConfig {
|
kernel: Some(KernelConfig {
|
||||||
|
@ -144,6 +144,7 @@ pub struct MemoryManager {
|
|||||||
shared: bool,
|
shared: bool,
|
||||||
hugepages: bool,
|
hugepages: bool,
|
||||||
hugepage_size: Option<u64>,
|
hugepage_size: Option<u64>,
|
||||||
|
prefault: bool,
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
sgx_epc_region: Option<SgxEpcRegion>,
|
sgx_epc_region: Option<SgxEpcRegion>,
|
||||||
user_provided_zones: bool,
|
user_provided_zones: bool,
|
||||||
@ -399,7 +400,7 @@ impl MemoryManager {
|
|||||||
fn create_memory_regions_from_zones(
|
fn create_memory_regions_from_zones(
|
||||||
ram_regions: &[(GuestAddress, usize)],
|
ram_regions: &[(GuestAddress, usize)],
|
||||||
zones: &[MemoryZoneConfig],
|
zones: &[MemoryZoneConfig],
|
||||||
prefault: bool,
|
prefault: Option<bool>,
|
||||||
) -> Result<(Vec<Arc<GuestRegionMmap>>, MemoryZones), Error> {
|
) -> Result<(Vec<Arc<GuestRegionMmap>>, MemoryZones), Error> {
|
||||||
let mut zones = zones.to_owned();
|
let mut zones = zones.to_owned();
|
||||||
let mut mem_regions = Vec::new();
|
let mut mem_regions = Vec::new();
|
||||||
@ -447,7 +448,10 @@ impl MemoryManager {
|
|||||||
file_offset,
|
file_offset,
|
||||||
region_start,
|
region_start,
|
||||||
region_size,
|
region_size,
|
||||||
prefault,
|
match prefault {
|
||||||
|
Some(pf) => pf,
|
||||||
|
None => zone.prefault,
|
||||||
|
},
|
||||||
zone.shared,
|
zone.shared,
|
||||||
zone.hugepages,
|
zone.hugepages,
|
||||||
zone.hugepage_size,
|
zone.hugepage_size,
|
||||||
@ -543,7 +547,7 @@ impl MemoryManager {
|
|||||||
pub fn new(
|
pub fn new(
|
||||||
vm: Arc<dyn hypervisor::Vm>,
|
vm: Arc<dyn hypervisor::Vm>,
|
||||||
config: &MemoryConfig,
|
config: &MemoryConfig,
|
||||||
prefault: bool,
|
prefault: Option<bool>,
|
||||||
phys_bits: u8,
|
phys_bits: u8,
|
||||||
#[cfg(feature = "tdx")] tdx_enabled: bool,
|
#[cfg(feature = "tdx")] tdx_enabled: bool,
|
||||||
) -> Result<Arc<Mutex<MemoryManager>>, Error> {
|
) -> Result<Arc<Mutex<MemoryManager>>, Error> {
|
||||||
@ -601,6 +605,7 @@ impl MemoryManager {
|
|||||||
host_numa_node: None,
|
host_numa_node: None,
|
||||||
hotplug_size: config.hotplug_size,
|
hotplug_size: config.hotplug_size,
|
||||||
hotplugged_size: config.hotplugged_size,
|
hotplugged_size: config.hotplugged_size,
|
||||||
|
prefault: config.prefault,
|
||||||
}];
|
}];
|
||||||
|
|
||||||
(config.size, zones)
|
(config.size, zones)
|
||||||
@ -716,12 +721,18 @@ impl MemoryManager {
|
|||||||
* virtio_devices::VIRTIO_MEM_ALIGN_SIZE,
|
* 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(
|
let region = MemoryManager::create_ram_region(
|
||||||
&None,
|
&None,
|
||||||
0,
|
0,
|
||||||
start_addr,
|
start_addr,
|
||||||
hotplug_size as usize,
|
hotplug_size as usize,
|
||||||
false,
|
match prefault {
|
||||||
|
Some(pf) => pf,
|
||||||
|
None => zone.prefault,
|
||||||
|
},
|
||||||
zone.shared,
|
zone.shared,
|
||||||
zone.hugepages,
|
zone.hugepages,
|
||||||
zone.hugepage_size,
|
zone.hugepage_size,
|
||||||
@ -810,6 +821,7 @@ impl MemoryManager {
|
|||||||
shared: config.shared,
|
shared: config.shared,
|
||||||
hugepages: config.hugepages,
|
hugepages: config.hugepages,
|
||||||
hugepage_size: config.hugepage_size,
|
hugepage_size: config.hugepage_size,
|
||||||
|
prefault: config.prefault,
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
sgx_epc_region: None,
|
sgx_epc_region: None,
|
||||||
user_provided_zones,
|
user_provided_zones,
|
||||||
@ -883,7 +895,7 @@ impl MemoryManager {
|
|||||||
let mm = MemoryManager::new(
|
let mm = MemoryManager::new(
|
||||||
vm,
|
vm,
|
||||||
config,
|
config,
|
||||||
prefault,
|
Some(prefault),
|
||||||
phys_bits,
|
phys_bits,
|
||||||
#[cfg(feature = "tdx")]
|
#[cfg(feature = "tdx")]
|
||||||
false,
|
false,
|
||||||
@ -1123,7 +1135,7 @@ impl MemoryManager {
|
|||||||
0,
|
0,
|
||||||
start_addr,
|
start_addr,
|
||||||
size,
|
size,
|
||||||
false,
|
self.prefault,
|
||||||
self.shared,
|
self.shared,
|
||||||
self.hugepages,
|
self.hugepages,
|
||||||
self.hugepage_size,
|
self.hugepage_size,
|
||||||
|
@ -762,7 +762,7 @@ impl Vm {
|
|||||||
let memory_manager = MemoryManager::new(
|
let memory_manager = MemoryManager::new(
|
||||||
vm.clone(),
|
vm.clone(),
|
||||||
&config.lock().unwrap().memory.clone(),
|
&config.lock().unwrap().memory.clone(),
|
||||||
false,
|
None,
|
||||||
phys_bits,
|
phys_bits,
|
||||||
#[cfg(feature = "tdx")]
|
#[cfg(feature = "tdx")]
|
||||||
tdx_enabled,
|
tdx_enabled,
|
||||||
@ -886,7 +886,7 @@ impl Vm {
|
|||||||
let memory_manager = MemoryManager::new(
|
let memory_manager = MemoryManager::new(
|
||||||
vm.clone(),
|
vm.clone(),
|
||||||
&config.lock().unwrap().memory.clone(),
|
&config.lock().unwrap().memory.clone(),
|
||||||
false,
|
None,
|
||||||
phys_bits,
|
phys_bits,
|
||||||
#[cfg(feature = "tdx")]
|
#[cfg(feature = "tdx")]
|
||||||
false,
|
false,
|
||||||
|
Loading…
Reference in New Issue
Block a user