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:
Rob Bradford 2021-04-29 12:10:44 +01:00 committed by Sebastien Boeuf
parent 2ad615cd32
commit 7e0ccce225
2 changed files with 53 additions and 12 deletions

View File

@ -984,11 +984,13 @@ mod unit_tests {
(
vec![
"cloud-hypervisor", "--kernel", "/path/to/kernel",
"--cpus", "boot=2",
"--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",
],
r#"{
"kernel": {"path": "/path/to/kernel"},
"cpus": {"boot_vcpus": 2, "max_vcpus": 2},
"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}
]
@ -998,11 +1000,13 @@ mod unit_tests {
(
vec![
"cloud-hypervisor", "--kernel", "/path/to/kernel",
"--cpus", "boot=2",
"--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",
],
r#"{
"kernel": {"path": "/path/to/kernel"},
"cpus": {"boot_vcpus": 2, "max_vcpus": 2},
"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}
]
@ -1163,13 +1167,14 @@ mod unit_tests {
(
vec![
"cloud-hypervisor", "--kernel", "/path/to/kernel",
"--memory", "shared=true",
"--memory", "shared=true", "--cpus", "boot=4",
"--fs",
"tag=virtiofs1,socket=/path/to/sock1,num_queues=4",
],
r#"{
"kernel": {"path": "/path/to/kernel"},
"memory" : { "shared": true, "size": 536870912 },
"cpus": {"boot_vcpus": 4, "max_vcpus": 4},
"fs": [
{"tag": "virtiofs1", "socket": "/path/to/sock1", "num_queues": 4}
]
@ -1179,13 +1184,14 @@ mod unit_tests {
(
vec![
"cloud-hypervisor", "--kernel", "/path/to/kernel",
"--memory", "shared=true",
"--memory", "shared=true", "--cpus", "boot=4",
"--fs",
"tag=virtiofs1,socket=/path/to/sock1,num_queues=4,queue_size=128"
],
r#"{
"kernel": {"path": "/path/to/kernel"},
"memory" : { "shared": true, "size": 536870912 },
"cpus": {"boot_vcpus": 4, "max_vcpus": 4},
"fs": [
{"tag": "virtiofs1", "socket": "/path/to/sock1", "num_queues": 4, "queue_size": 128}
]
@ -1195,13 +1201,14 @@ mod unit_tests {
(
vec![
"cloud-hypervisor", "--kernel", "/path/to/kernel",
"--memory", "shared=true",
"--memory", "shared=true", "--cpus", "boot=4",
"--fs",
"tag=virtiofs1,socket=/path/to/sock1,num_queues=4,queue_size=128,dax=on"
],
r#"{
"kernel": {"path": "/path/to/kernel"},
"memory" : { "shared": true, "size": 536870912 },
"cpus": {"boot_vcpus": 4, "max_vcpus": 4},
"fs": [
{"tag": "virtiofs1", "socket": "/path/to/sock1", "num_queues": 4, "queue_size": 128}
]
@ -1211,13 +1218,14 @@ mod unit_tests {
(
vec![
"cloud-hypervisor", "--kernel", "/path/to/kernel",
"--memory", "shared=true",
"--memory", "shared=true", "--cpus", "boot=4",
"--fs",
"tag=virtiofs1,socket=/path/to/sock1,num_queues=4,queue_size=128,dax=on"
],
r#"{
"kernel": {"path": "/path/to/kernel"},
"memory" : { "shared": true, "size": 536870912 },
"cpus": {"boot_vcpus": 4, "max_vcpus": 4},
"fs": [
{"tag": "virtiofs1", "socket": "/path/to/sock1", "num_queues": 4, "queue_size": 128, "dax": true}
]
@ -1227,13 +1235,14 @@ mod unit_tests {
(
vec![
"cloud-hypervisor", "--kernel", "/path/to/kernel",
"--memory", "shared=true",
"--memory", "shared=true", "--cpus", "boot=4",
"--fs",
"tag=virtiofs1,socket=/path/to/sock1,num_queues=4,queue_size=128"
],
r#"{
"kernel": {"path": "/path/to/kernel"},
"memory" : { "shared": true, "size": 536870912 },
"cpus": {"boot_vcpus": 4, "max_vcpus": 4},
"fs": [
{"tag": "virtiofs1", "socket": "/path/to/sock1", "num_queues": 4, "queue_size": 128, "dax": true}
]
@ -1243,13 +1252,14 @@ mod unit_tests {
(
vec![
"cloud-hypervisor", "--kernel", "/path/to/kernel",
"--memory", "shared=true",
"--memory", "shared=true", "--cpus", "boot=4",
"--fs",
"tag=virtiofs1,socket=/path/to/sock1,num_queues=4,queue_size=128,cache_size=8589934592"
],
r#"{
"kernel": {"path": "/path/to/kernel"},
"memory" : { "shared": true, "size": 536870912 },
"cpus": {"boot_vcpus": 4, "max_vcpus": 4},
"fs": [
{"tag": "virtiofs1", "socket": "/path/to/sock1", "num_queues": 4, "queue_size": 128}
]
@ -1259,13 +1269,14 @@ mod unit_tests {
(
vec![
"cloud-hypervisor", "--kernel", "/path/to/kernel",
"--memory", "shared=true",
"--memory", "shared=true", "--cpus", "boot=4",
"--fs",
"tag=virtiofs1,socket=/path/to/sock1,num_queues=4,queue_size=128"
],
r#"{
"kernel": {"path": "/path/to/kernel"},
"memory" : { "shared": true, "size": 536870912 },
"cpus": {"boot_vcpus": 4, "max_vcpus": 4},
"fs": [
{"tag": "virtiofs1", "socket": "/path/to/sock1", "num_queues": 4, "queue_size": 128, "cache_size": 8589934592}
]
@ -1275,13 +1286,14 @@ mod unit_tests {
(
vec![
"cloud-hypervisor", "--kernel", "/path/to/kernel",
"--memory", "shared=true",
"--memory", "shared=true","--cpus", "boot=4",
"--fs",
"tag=virtiofs1,socket=/path/to/sock1,num_queues=4,queue_size=128,cache_size=4294967296"
],
r#"{
"kernel": {"path": "/path/to/kernel"},
"memory" : { "shared": true, "size": 536870912 },
"cpus": {"boot_vcpus": 4, "max_vcpus": 4},
"fs": [
{"tag": "virtiofs1", "socket": "/path/to/sock1", "num_queues": 4, "queue_size": 128, "cache_size": 4294967296}
]
@ -1291,13 +1303,14 @@ mod unit_tests {
(
vec![
"cloud-hypervisor", "--kernel", "/path/to/kernel",
"--memory", "shared=true",
"--memory", "shared=true","--cpus", "boot=4",
"--fs",
"tag=virtiofs1,socket=/path/to/sock1,num_queues=4,queue_size=128,cache_size=4294967296"
],
r#"{
"kernel": {"path": "/path/to/kernel"},
"memory" : { "shared": true, "size": 536870912 },
"cpus": {"boot_vcpus": 4, "max_vcpus": 4},
"fs": [
{"tag": "virtiofs1", "socket": "/path/to/sock1", "num_queues": 4, "queue_size": 128}
]

View File

@ -126,6 +126,8 @@ pub enum ValidationError {
// CPU Hotplug not permitted with TDX
#[cfg(feature = "tdx")]
TdxNoCpuHotplug,
// Insuffient vCPUs for queues
TooManyQueues,
}
type ValidationResult<T> = std::result::Result<T, ValidationError>;
@ -166,6 +168,9 @@ impl fmt::Display for ValidationError {
TdxNoCpuHotplug => {
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,
})
}
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)]
@ -1075,11 +1088,10 @@ impl NetConfig {
fds,
rate_limiter_config,
};
config.validate().map_err(Error::Validation)?;
Ok(config)
}
pub fn validate(&self) -> ValidationResult<()> {
pub fn validate(&self, vm_config: &VmConfig) -> ValidationResult<()> {
if self.num_queues < 2 {
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(())
}
}
@ -1264,6 +1280,14 @@ impl FsConfig {
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)]
@ -1719,6 +1743,7 @@ impl VmConfig {
if disk.vhost_user && disk.vhost_socket.is_none() {
return Err(ValidationError::VhostUserMissingSocket);
}
disk.validate(self)?;
}
}
@ -1727,7 +1752,7 @@ impl VmConfig {
if net.vhost_user && !self.memory.shared {
return Err(ValidationError::VhostUserRequiresSharedMemory);
}
net.validate()?;
net.validate(self)?;
}
}
@ -1735,6 +1760,9 @@ impl VmConfig {
if !fses.is_empty() && !self.memory.shared {
return Err(ValidationError::VhostUserRequiresSharedMemory);
}
for fs in fses {
fs.validate(self)?;
}
}
if let Some(t) = &self.cpus.topology {