vmm: Improve handling of shared memory backing

As huge pages are always MAP_SHARED then where the shared memory would
be checked (for vhost-user and local migration) we can also check
instead for huge pages.

The checking is also extended to cover the memory zones based
configuration as well.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
This commit is contained in:
Rob Bradford
2022-10-31 13:39:11 +00:00
parent 99d9a3d299
commit f4495de143
2 changed files with 31 additions and 9 deletions
+29 -6
View File
@@ -180,7 +180,10 @@ impl fmt::Display for ValidationError {
CpusMaxLowerThanBoot => write!(f, "Max CPUs lower than boot CPUs"), CpusMaxLowerThanBoot => write!(f, "Max CPUs lower than boot CPUs"),
DiskSocketAndPath => write!(f, "Disk path and vhost socket both provided"), DiskSocketAndPath => write!(f, "Disk path and vhost socket both provided"),
VhostUserRequiresSharedMemory => { VhostUserRequiresSharedMemory => {
write!(f, "Using vhost-user requires using shared memory") write!(
f,
"Using vhost-user requires using shared memory or huge pages"
)
} }
VhostUserMissingSocket => write!(f, "No socket provided when using vhost-user"), VhostUserMissingSocket => write!(f, "No socket provided when using vhost-user"),
IommuUnsupported => write!(f, "Using an IOMMU without PCI support is unsupported"), IommuUnsupported => write!(f, "Using an IOMMU without PCI support is unsupported"),
@@ -216,7 +219,10 @@ impl fmt::Display for ValidationError {
write!(f, "Number of vCPUs is insufficient for number of queues") write!(f, "Number of vCPUs is insufficient for number of queues")
} }
UserDevicesRequireSharedMemory => { UserDevicesRequireSharedMemory => {
write!(f, "Using user devices requires using shared memory") write!(
f,
"Using user devices requires using shared memory or huge pages"
)
} }
MemoryZoneReused(s, u1, u2) => { MemoryZoneReused(s, u1, u2) => {
write!( write!(
@@ -1756,6 +1762,23 @@ impl VmConfig {
Ok(()) Ok(())
} }
pub fn backed_by_shared_memory(&self) -> bool {
if self.memory.shared || self.memory.hugepages {
return true;
}
if self.memory.size == 0 {
for zone in self.memory.zones.as_ref().unwrap() {
if !zone.shared && !zone.hugepages {
return false;
}
}
true
} else {
false
}
}
// Also enables virtio-iommu if the config needs it // Also enables virtio-iommu if the config needs it
// Returns the list of unique identifiers provided through the // Returns the list of unique identifiers provided through the
// configuration. // configuration.
@@ -1800,7 +1823,7 @@ impl VmConfig {
if disk.vhost_socket.as_ref().and(disk.path.as_ref()).is_some() { if disk.vhost_socket.as_ref().and(disk.path.as_ref()).is_some() {
return Err(ValidationError::DiskSocketAndPath); return Err(ValidationError::DiskSocketAndPath);
} }
if disk.vhost_user && !self.memory.shared { if disk.vhost_user && !self.backed_by_shared_memory() {
return Err(ValidationError::VhostUserRequiresSharedMemory); return Err(ValidationError::VhostUserRequiresSharedMemory);
} }
if disk.vhost_user && disk.vhost_socket.is_none() { if disk.vhost_user && disk.vhost_socket.is_none() {
@@ -1815,7 +1838,7 @@ impl VmConfig {
if let Some(nets) = &self.net { if let Some(nets) = &self.net {
for net in nets { for net in nets {
if net.vhost_user && !self.memory.shared { if net.vhost_user && !self.backed_by_shared_memory() {
return Err(ValidationError::VhostUserRequiresSharedMemory); return Err(ValidationError::VhostUserRequiresSharedMemory);
} }
net.validate(self)?; net.validate(self)?;
@@ -1826,7 +1849,7 @@ impl VmConfig {
} }
if let Some(fses) = &self.fs { if let Some(fses) = &self.fs {
if !fses.is_empty() && !self.memory.shared { if !fses.is_empty() && !self.backed_by_shared_memory() {
return Err(ValidationError::VhostUserRequiresSharedMemory); return Err(ValidationError::VhostUserRequiresSharedMemory);
} }
for fs in fses { for fs in fses {
@@ -1881,7 +1904,7 @@ impl VmConfig {
} }
if let Some(user_devices) = &self.user_devices { if let Some(user_devices) = &self.user_devices {
if !user_devices.is_empty() && !self.memory.shared { if !user_devices.is_empty() && !self.backed_by_shared_memory() {
return Err(ValidationError::UserDevicesRequireSharedMemory); return Err(ValidationError::UserDevicesRequireSharedMemory);
} }
+2 -3
View File
@@ -1606,12 +1606,11 @@ impl Vmm {
.unwrap() .unwrap()
.lock() .lock()
.unwrap() .unwrap()
.memory .backed_by_shared_memory()
.shared
&& send_data_migration.local && send_data_migration.local
{ {
return Err(MigratableError::MigrateSend(anyhow!( return Err(MigratableError::MigrateSend(anyhow!(
"Local migration requires shared memory enabled" "Local migration requires shared memory or hugepages enabled"
))); )));
} }