mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2024-10-02 11:35:46 +00:00
vmm, doc: Forbid same memory zone in multiple NUMA nodes
It is forbidden that the same memory zone belongs to more than one NUMA node. This commit adds related validation to the `--numa` parameter to prevent the user from specifying such configuration. Signed-off-by: Henry Wang <Henry.Wang@arm.com>
This commit is contained in:
parent
f3197c3833
commit
bcae6c41e3
@ -441,6 +441,10 @@ Multiple values can be provided to define the list. Each value is a string
|
|||||||
referring to an existing memory zone identifier. Values are separated from
|
referring to an existing memory zone identifier. Values are separated from
|
||||||
each other with the `:` separator.
|
each other with the `:` separator.
|
||||||
|
|
||||||
|
Note that a memory zone must belong to a single NUMA node. The following
|
||||||
|
configuration is incorrect, therefore not allowed:
|
||||||
|
`--numa guest_numa_id=0,memory_zones=mem0 guest_numa_id=1,memory_zones=mem0`
|
||||||
|
|
||||||
_Example_
|
_Example_
|
||||||
|
|
||||||
```
|
```
|
||||||
|
@ -8,6 +8,7 @@ use net_util::MacAddr;
|
|||||||
use option_parser::{
|
use option_parser::{
|
||||||
ByteSized, IntegerList, OptionParser, OptionParserError, StringList, Toggle, TupleTwoIntegers,
|
ByteSized, IntegerList, OptionParser, OptionParserError, StringList, Toggle, TupleTwoIntegers,
|
||||||
};
|
};
|
||||||
|
use std::collections::HashMap;
|
||||||
use std::convert::From;
|
use std::convert::From;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::net::Ipv4Addr;
|
use std::net::Ipv4Addr;
|
||||||
@ -126,20 +127,22 @@ pub enum ValidationError {
|
|||||||
VnetQueueFdMismatch,
|
VnetQueueFdMismatch,
|
||||||
/// Using reserved fd
|
/// Using reserved fd
|
||||||
VnetReservedFd,
|
VnetReservedFd,
|
||||||
// Hugepages not turned on
|
/// Hugepages not turned on
|
||||||
HugePageSizeWithoutHugePages,
|
HugePageSizeWithoutHugePages,
|
||||||
// Huge page size is not power of 2
|
/// Huge page size is not power of 2
|
||||||
InvalidHugePageSize(u64),
|
InvalidHugePageSize(u64),
|
||||||
// CPU Hotplug not permitted with TDX
|
/// CPU Hotplug not permitted with TDX
|
||||||
#[cfg(feature = "tdx")]
|
#[cfg(feature = "tdx")]
|
||||||
TdxNoCpuHotplug,
|
TdxNoCpuHotplug,
|
||||||
// Specifying kernel not permitted with TDX
|
/// Specifying kernel not permitted with TDX
|
||||||
#[cfg(feature = "tdx")]
|
#[cfg(feature = "tdx")]
|
||||||
TdxKernelSpecified,
|
TdxKernelSpecified,
|
||||||
// Insuffient vCPUs for queues
|
/// Insuffient vCPUs for queues
|
||||||
TooManyQueues,
|
TooManyQueues,
|
||||||
// Need shared memory for vfio-user
|
/// Need shared memory for vfio-user
|
||||||
UserDevicesRequireSharedMemory,
|
UserDevicesRequireSharedMemory,
|
||||||
|
/// Memory zone is reused across NUMA nodes
|
||||||
|
MemoryZoneReused(String, u32, u32),
|
||||||
}
|
}
|
||||||
|
|
||||||
type ValidationResult<T> = std::result::Result<T, ValidationError>;
|
type ValidationResult<T> = std::result::Result<T, ValidationError>;
|
||||||
@ -190,6 +193,13 @@ impl fmt::Display for ValidationError {
|
|||||||
UserDevicesRequireSharedMemory => {
|
UserDevicesRequireSharedMemory => {
|
||||||
write!(f, "Using user devices requires using shared memory")
|
write!(f, "Using user devices requires using shared memory")
|
||||||
}
|
}
|
||||||
|
MemoryZoneReused(s, u1, u2) => {
|
||||||
|
write!(
|
||||||
|
f,
|
||||||
|
"Memory zone: {} belongs to multiple NUMA nodes {} and {}",
|
||||||
|
s, u1, u2
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1915,6 +1925,27 @@ impl VmConfig {
|
|||||||
return Err(ValidationError::UserDevicesRequireSharedMemory);
|
return Err(ValidationError::UserDevicesRequireSharedMemory);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let Some(numa) = &self.numa {
|
||||||
|
let mut used_numa_node_memory_zones = HashMap::new();
|
||||||
|
for numa_node in numa.iter() {
|
||||||
|
for memory_zone in numa_node.memory_zones.clone().unwrap().iter() {
|
||||||
|
if !used_numa_node_memory_zones.contains_key(memory_zone) {
|
||||||
|
used_numa_node_memory_zones
|
||||||
|
.insert(memory_zone.to_string(), numa_node.guest_numa_id);
|
||||||
|
} else {
|
||||||
|
return Err(ValidationError::MemoryZoneReused(
|
||||||
|
memory_zone.to_string(),
|
||||||
|
*used_numa_node_memory_zones
|
||||||
|
.get(&memory_zone.to_string())
|
||||||
|
.unwrap(),
|
||||||
|
numa_node.guest_numa_id,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user