mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2025-01-03 19:35:21 +00:00
vmm: config: Validate that vCPUs is sufficient for MQ queue count
Fixes: #2563 Signed-off-by: Rob Bradford <robert.bradford@intel.com>
This commit is contained in:
parent
2ad615cd32
commit
7e0ccce225
31
src/main.rs
31
src/main.rs
@ -984,11 +984,13 @@ mod unit_tests {
|
|||||||
(
|
(
|
||||||
vec![
|
vec![
|
||||||
"cloud-hypervisor", "--kernel", "/path/to/kernel",
|
"cloud-hypervisor", "--kernel", "/path/to/kernel",
|
||||||
|
"--cpus", "boot=2",
|
||||||
"--net",
|
"--net",
|
||||||
"mac=12:34:56:78:90:ab,host_mac=34:56:78:90:ab:cd,tap=tap0,ip=1.2.3.4,mask=5.6.7.8,num_queues=4",
|
"mac=12:34:56:78:90:ab,host_mac=34:56:78:90:ab:cd,tap=tap0,ip=1.2.3.4,mask=5.6.7.8,num_queues=4",
|
||||||
],
|
],
|
||||||
r#"{
|
r#"{
|
||||||
"kernel": {"path": "/path/to/kernel"},
|
"kernel": {"path": "/path/to/kernel"},
|
||||||
|
"cpus": {"boot_vcpus": 2, "max_vcpus": 2},
|
||||||
"net": [
|
"net": [
|
||||||
{"mac": "12:34:56:78:90:ab", "host_mac": "34:56:78:90:ab:cd", "tap": "tap0", "ip": "1.2.3.4", "mask": "5.6.7.8", "num_queues": 4}
|
{"mac": "12:34:56:78:90:ab", "host_mac": "34:56:78:90:ab:cd", "tap": "tap0", "ip": "1.2.3.4", "mask": "5.6.7.8", "num_queues": 4}
|
||||||
]
|
]
|
||||||
@ -998,11 +1000,13 @@ mod unit_tests {
|
|||||||
(
|
(
|
||||||
vec![
|
vec![
|
||||||
"cloud-hypervisor", "--kernel", "/path/to/kernel",
|
"cloud-hypervisor", "--kernel", "/path/to/kernel",
|
||||||
|
"--cpus", "boot=2",
|
||||||
"--net",
|
"--net",
|
||||||
"mac=12:34:56:78:90:ab,host_mac=34:56:78:90:ab:cd,tap=tap0,ip=1.2.3.4,mask=5.6.7.8,num_queues=4,queue_size=128",
|
"mac=12:34:56:78:90:ab,host_mac=34:56:78:90:ab:cd,tap=tap0,ip=1.2.3.4,mask=5.6.7.8,num_queues=4,queue_size=128",
|
||||||
],
|
],
|
||||||
r#"{
|
r#"{
|
||||||
"kernel": {"path": "/path/to/kernel"},
|
"kernel": {"path": "/path/to/kernel"},
|
||||||
|
"cpus": {"boot_vcpus": 2, "max_vcpus": 2},
|
||||||
"net": [
|
"net": [
|
||||||
{"mac": "12:34:56:78:90:ab", "host_mac": "34:56:78:90:ab:cd", "tap": "tap0", "ip": "1.2.3.4", "mask": "5.6.7.8", "num_queues": 4, "queue_size": 128}
|
{"mac": "12:34:56:78:90:ab", "host_mac": "34:56:78:90:ab:cd", "tap": "tap0", "ip": "1.2.3.4", "mask": "5.6.7.8", "num_queues": 4, "queue_size": 128}
|
||||||
]
|
]
|
||||||
@ -1163,13 +1167,14 @@ mod unit_tests {
|
|||||||
(
|
(
|
||||||
vec![
|
vec![
|
||||||
"cloud-hypervisor", "--kernel", "/path/to/kernel",
|
"cloud-hypervisor", "--kernel", "/path/to/kernel",
|
||||||
"--memory", "shared=true",
|
"--memory", "shared=true", "--cpus", "boot=4",
|
||||||
"--fs",
|
"--fs",
|
||||||
"tag=virtiofs1,socket=/path/to/sock1,num_queues=4",
|
"tag=virtiofs1,socket=/path/to/sock1,num_queues=4",
|
||||||
],
|
],
|
||||||
r#"{
|
r#"{
|
||||||
"kernel": {"path": "/path/to/kernel"},
|
"kernel": {"path": "/path/to/kernel"},
|
||||||
"memory" : { "shared": true, "size": 536870912 },
|
"memory" : { "shared": true, "size": 536870912 },
|
||||||
|
"cpus": {"boot_vcpus": 4, "max_vcpus": 4},
|
||||||
"fs": [
|
"fs": [
|
||||||
{"tag": "virtiofs1", "socket": "/path/to/sock1", "num_queues": 4}
|
{"tag": "virtiofs1", "socket": "/path/to/sock1", "num_queues": 4}
|
||||||
]
|
]
|
||||||
@ -1179,13 +1184,14 @@ mod unit_tests {
|
|||||||
(
|
(
|
||||||
vec![
|
vec![
|
||||||
"cloud-hypervisor", "--kernel", "/path/to/kernel",
|
"cloud-hypervisor", "--kernel", "/path/to/kernel",
|
||||||
"--memory", "shared=true",
|
"--memory", "shared=true", "--cpus", "boot=4",
|
||||||
"--fs",
|
"--fs",
|
||||||
"tag=virtiofs1,socket=/path/to/sock1,num_queues=4,queue_size=128"
|
"tag=virtiofs1,socket=/path/to/sock1,num_queues=4,queue_size=128"
|
||||||
],
|
],
|
||||||
r#"{
|
r#"{
|
||||||
"kernel": {"path": "/path/to/kernel"},
|
"kernel": {"path": "/path/to/kernel"},
|
||||||
"memory" : { "shared": true, "size": 536870912 },
|
"memory" : { "shared": true, "size": 536870912 },
|
||||||
|
"cpus": {"boot_vcpus": 4, "max_vcpus": 4},
|
||||||
"fs": [
|
"fs": [
|
||||||
{"tag": "virtiofs1", "socket": "/path/to/sock1", "num_queues": 4, "queue_size": 128}
|
{"tag": "virtiofs1", "socket": "/path/to/sock1", "num_queues": 4, "queue_size": 128}
|
||||||
]
|
]
|
||||||
@ -1195,13 +1201,14 @@ mod unit_tests {
|
|||||||
(
|
(
|
||||||
vec![
|
vec![
|
||||||
"cloud-hypervisor", "--kernel", "/path/to/kernel",
|
"cloud-hypervisor", "--kernel", "/path/to/kernel",
|
||||||
"--memory", "shared=true",
|
"--memory", "shared=true", "--cpus", "boot=4",
|
||||||
"--fs",
|
"--fs",
|
||||||
"tag=virtiofs1,socket=/path/to/sock1,num_queues=4,queue_size=128,dax=on"
|
"tag=virtiofs1,socket=/path/to/sock1,num_queues=4,queue_size=128,dax=on"
|
||||||
],
|
],
|
||||||
r#"{
|
r#"{
|
||||||
"kernel": {"path": "/path/to/kernel"},
|
"kernel": {"path": "/path/to/kernel"},
|
||||||
"memory" : { "shared": true, "size": 536870912 },
|
"memory" : { "shared": true, "size": 536870912 },
|
||||||
|
"cpus": {"boot_vcpus": 4, "max_vcpus": 4},
|
||||||
"fs": [
|
"fs": [
|
||||||
{"tag": "virtiofs1", "socket": "/path/to/sock1", "num_queues": 4, "queue_size": 128}
|
{"tag": "virtiofs1", "socket": "/path/to/sock1", "num_queues": 4, "queue_size": 128}
|
||||||
]
|
]
|
||||||
@ -1211,13 +1218,14 @@ mod unit_tests {
|
|||||||
(
|
(
|
||||||
vec![
|
vec![
|
||||||
"cloud-hypervisor", "--kernel", "/path/to/kernel",
|
"cloud-hypervisor", "--kernel", "/path/to/kernel",
|
||||||
"--memory", "shared=true",
|
"--memory", "shared=true", "--cpus", "boot=4",
|
||||||
"--fs",
|
"--fs",
|
||||||
"tag=virtiofs1,socket=/path/to/sock1,num_queues=4,queue_size=128,dax=on"
|
"tag=virtiofs1,socket=/path/to/sock1,num_queues=4,queue_size=128,dax=on"
|
||||||
],
|
],
|
||||||
r#"{
|
r#"{
|
||||||
"kernel": {"path": "/path/to/kernel"},
|
"kernel": {"path": "/path/to/kernel"},
|
||||||
"memory" : { "shared": true, "size": 536870912 },
|
"memory" : { "shared": true, "size": 536870912 },
|
||||||
|
"cpus": {"boot_vcpus": 4, "max_vcpus": 4},
|
||||||
"fs": [
|
"fs": [
|
||||||
{"tag": "virtiofs1", "socket": "/path/to/sock1", "num_queues": 4, "queue_size": 128, "dax": true}
|
{"tag": "virtiofs1", "socket": "/path/to/sock1", "num_queues": 4, "queue_size": 128, "dax": true}
|
||||||
]
|
]
|
||||||
@ -1227,13 +1235,14 @@ mod unit_tests {
|
|||||||
(
|
(
|
||||||
vec![
|
vec![
|
||||||
"cloud-hypervisor", "--kernel", "/path/to/kernel",
|
"cloud-hypervisor", "--kernel", "/path/to/kernel",
|
||||||
"--memory", "shared=true",
|
"--memory", "shared=true", "--cpus", "boot=4",
|
||||||
"--fs",
|
"--fs",
|
||||||
"tag=virtiofs1,socket=/path/to/sock1,num_queues=4,queue_size=128"
|
"tag=virtiofs1,socket=/path/to/sock1,num_queues=4,queue_size=128"
|
||||||
],
|
],
|
||||||
r#"{
|
r#"{
|
||||||
"kernel": {"path": "/path/to/kernel"},
|
"kernel": {"path": "/path/to/kernel"},
|
||||||
"memory" : { "shared": true, "size": 536870912 },
|
"memory" : { "shared": true, "size": 536870912 },
|
||||||
|
"cpus": {"boot_vcpus": 4, "max_vcpus": 4},
|
||||||
"fs": [
|
"fs": [
|
||||||
{"tag": "virtiofs1", "socket": "/path/to/sock1", "num_queues": 4, "queue_size": 128, "dax": true}
|
{"tag": "virtiofs1", "socket": "/path/to/sock1", "num_queues": 4, "queue_size": 128, "dax": true}
|
||||||
]
|
]
|
||||||
@ -1243,13 +1252,14 @@ mod unit_tests {
|
|||||||
(
|
(
|
||||||
vec![
|
vec![
|
||||||
"cloud-hypervisor", "--kernel", "/path/to/kernel",
|
"cloud-hypervisor", "--kernel", "/path/to/kernel",
|
||||||
"--memory", "shared=true",
|
"--memory", "shared=true", "--cpus", "boot=4",
|
||||||
"--fs",
|
"--fs",
|
||||||
"tag=virtiofs1,socket=/path/to/sock1,num_queues=4,queue_size=128,cache_size=8589934592"
|
"tag=virtiofs1,socket=/path/to/sock1,num_queues=4,queue_size=128,cache_size=8589934592"
|
||||||
],
|
],
|
||||||
r#"{
|
r#"{
|
||||||
"kernel": {"path": "/path/to/kernel"},
|
"kernel": {"path": "/path/to/kernel"},
|
||||||
"memory" : { "shared": true, "size": 536870912 },
|
"memory" : { "shared": true, "size": 536870912 },
|
||||||
|
"cpus": {"boot_vcpus": 4, "max_vcpus": 4},
|
||||||
"fs": [
|
"fs": [
|
||||||
{"tag": "virtiofs1", "socket": "/path/to/sock1", "num_queues": 4, "queue_size": 128}
|
{"tag": "virtiofs1", "socket": "/path/to/sock1", "num_queues": 4, "queue_size": 128}
|
||||||
]
|
]
|
||||||
@ -1259,13 +1269,14 @@ mod unit_tests {
|
|||||||
(
|
(
|
||||||
vec![
|
vec![
|
||||||
"cloud-hypervisor", "--kernel", "/path/to/kernel",
|
"cloud-hypervisor", "--kernel", "/path/to/kernel",
|
||||||
"--memory", "shared=true",
|
"--memory", "shared=true", "--cpus", "boot=4",
|
||||||
"--fs",
|
"--fs",
|
||||||
"tag=virtiofs1,socket=/path/to/sock1,num_queues=4,queue_size=128"
|
"tag=virtiofs1,socket=/path/to/sock1,num_queues=4,queue_size=128"
|
||||||
],
|
],
|
||||||
r#"{
|
r#"{
|
||||||
"kernel": {"path": "/path/to/kernel"},
|
"kernel": {"path": "/path/to/kernel"},
|
||||||
"memory" : { "shared": true, "size": 536870912 },
|
"memory" : { "shared": true, "size": 536870912 },
|
||||||
|
"cpus": {"boot_vcpus": 4, "max_vcpus": 4},
|
||||||
"fs": [
|
"fs": [
|
||||||
{"tag": "virtiofs1", "socket": "/path/to/sock1", "num_queues": 4, "queue_size": 128, "cache_size": 8589934592}
|
{"tag": "virtiofs1", "socket": "/path/to/sock1", "num_queues": 4, "queue_size": 128, "cache_size": 8589934592}
|
||||||
]
|
]
|
||||||
@ -1275,13 +1286,14 @@ mod unit_tests {
|
|||||||
(
|
(
|
||||||
vec![
|
vec![
|
||||||
"cloud-hypervisor", "--kernel", "/path/to/kernel",
|
"cloud-hypervisor", "--kernel", "/path/to/kernel",
|
||||||
"--memory", "shared=true",
|
"--memory", "shared=true","--cpus", "boot=4",
|
||||||
"--fs",
|
"--fs",
|
||||||
"tag=virtiofs1,socket=/path/to/sock1,num_queues=4,queue_size=128,cache_size=4294967296"
|
"tag=virtiofs1,socket=/path/to/sock1,num_queues=4,queue_size=128,cache_size=4294967296"
|
||||||
],
|
],
|
||||||
r#"{
|
r#"{
|
||||||
"kernel": {"path": "/path/to/kernel"},
|
"kernel": {"path": "/path/to/kernel"},
|
||||||
"memory" : { "shared": true, "size": 536870912 },
|
"memory" : { "shared": true, "size": 536870912 },
|
||||||
|
"cpus": {"boot_vcpus": 4, "max_vcpus": 4},
|
||||||
"fs": [
|
"fs": [
|
||||||
{"tag": "virtiofs1", "socket": "/path/to/sock1", "num_queues": 4, "queue_size": 128, "cache_size": 4294967296}
|
{"tag": "virtiofs1", "socket": "/path/to/sock1", "num_queues": 4, "queue_size": 128, "cache_size": 4294967296}
|
||||||
]
|
]
|
||||||
@ -1291,13 +1303,14 @@ mod unit_tests {
|
|||||||
(
|
(
|
||||||
vec![
|
vec![
|
||||||
"cloud-hypervisor", "--kernel", "/path/to/kernel",
|
"cloud-hypervisor", "--kernel", "/path/to/kernel",
|
||||||
"--memory", "shared=true",
|
"--memory", "shared=true","--cpus", "boot=4",
|
||||||
"--fs",
|
"--fs",
|
||||||
"tag=virtiofs1,socket=/path/to/sock1,num_queues=4,queue_size=128,cache_size=4294967296"
|
"tag=virtiofs1,socket=/path/to/sock1,num_queues=4,queue_size=128,cache_size=4294967296"
|
||||||
],
|
],
|
||||||
r#"{
|
r#"{
|
||||||
"kernel": {"path": "/path/to/kernel"},
|
"kernel": {"path": "/path/to/kernel"},
|
||||||
"memory" : { "shared": true, "size": 536870912 },
|
"memory" : { "shared": true, "size": 536870912 },
|
||||||
|
"cpus": {"boot_vcpus": 4, "max_vcpus": 4},
|
||||||
"fs": [
|
"fs": [
|
||||||
{"tag": "virtiofs1", "socket": "/path/to/sock1", "num_queues": 4, "queue_size": 128}
|
{"tag": "virtiofs1", "socket": "/path/to/sock1", "num_queues": 4, "queue_size": 128}
|
||||||
]
|
]
|
||||||
|
@ -126,6 +126,8 @@ pub enum ValidationError {
|
|||||||
// CPU Hotplug not permitted with TDX
|
// CPU Hotplug not permitted with TDX
|
||||||
#[cfg(feature = "tdx")]
|
#[cfg(feature = "tdx")]
|
||||||
TdxNoCpuHotplug,
|
TdxNoCpuHotplug,
|
||||||
|
// Insuffient vCPUs for queues
|
||||||
|
TooManyQueues,
|
||||||
}
|
}
|
||||||
|
|
||||||
type ValidationResult<T> = std::result::Result<T, ValidationError>;
|
type ValidationResult<T> = std::result::Result<T, ValidationError>;
|
||||||
@ -166,6 +168,9 @@ impl fmt::Display for ValidationError {
|
|||||||
TdxNoCpuHotplug => {
|
TdxNoCpuHotplug => {
|
||||||
write!(f, "CPU hotplug not possible with TDX")
|
write!(f, "CPU hotplug not possible with TDX")
|
||||||
}
|
}
|
||||||
|
TooManyQueues => {
|
||||||
|
write!(f, "Number of vCPUs is insufficient for number of queues")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -863,6 +868,14 @@ impl DiskConfig {
|
|||||||
disable_io_uring,
|
disable_io_uring,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn validate(&self, vm_config: &VmConfig) -> ValidationResult<()> {
|
||||||
|
if self.num_queues > vm_config.cpus.boot_vcpus as usize {
|
||||||
|
return Err(ValidationError::TooManyQueues);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
|
#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
|
||||||
@ -1075,11 +1088,10 @@ impl NetConfig {
|
|||||||
fds,
|
fds,
|
||||||
rate_limiter_config,
|
rate_limiter_config,
|
||||||
};
|
};
|
||||||
config.validate().map_err(Error::Validation)?;
|
|
||||||
Ok(config)
|
Ok(config)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn validate(&self) -> ValidationResult<()> {
|
pub fn validate(&self, vm_config: &VmConfig) -> ValidationResult<()> {
|
||||||
if self.num_queues < 2 {
|
if self.num_queues < 2 {
|
||||||
return Err(ValidationError::VnetQueueLowerThan2);
|
return Err(ValidationError::VnetQueueLowerThan2);
|
||||||
}
|
}
|
||||||
@ -1096,6 +1108,10 @@ impl NetConfig {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (self.num_queues / 2) > vm_config.cpus.boot_vcpus as usize {
|
||||||
|
return Err(ValidationError::TooManyQueues);
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1264,6 +1280,14 @@ impl FsConfig {
|
|||||||
id,
|
id,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn validate(&self, vm_config: &VmConfig) -> ValidationResult<()> {
|
||||||
|
if self.num_queues > vm_config.cpus.boot_vcpus as usize {
|
||||||
|
return Err(ValidationError::TooManyQueues);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Deserialize, Serialize, Default)]
|
#[derive(Clone, Debug, PartialEq, Deserialize, Serialize, Default)]
|
||||||
@ -1719,6 +1743,7 @@ impl VmConfig {
|
|||||||
if disk.vhost_user && disk.vhost_socket.is_none() {
|
if disk.vhost_user && disk.vhost_socket.is_none() {
|
||||||
return Err(ValidationError::VhostUserMissingSocket);
|
return Err(ValidationError::VhostUserMissingSocket);
|
||||||
}
|
}
|
||||||
|
disk.validate(self)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1727,7 +1752,7 @@ impl VmConfig {
|
|||||||
if net.vhost_user && !self.memory.shared {
|
if net.vhost_user && !self.memory.shared {
|
||||||
return Err(ValidationError::VhostUserRequiresSharedMemory);
|
return Err(ValidationError::VhostUserRequiresSharedMemory);
|
||||||
}
|
}
|
||||||
net.validate()?;
|
net.validate(self)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1735,6 +1760,9 @@ impl VmConfig {
|
|||||||
if !fses.is_empty() && !self.memory.shared {
|
if !fses.is_empty() && !self.memory.shared {
|
||||||
return Err(ValidationError::VhostUserRequiresSharedMemory);
|
return Err(ValidationError::VhostUserRequiresSharedMemory);
|
||||||
}
|
}
|
||||||
|
for fs in fses {
|
||||||
|
fs.validate(self)?;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(t) = &self.cpus.topology {
|
if let Some(t) = &self.cpus.topology {
|
||||||
|
Loading…
Reference in New Issue
Block a user