mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2025-02-22 11:22:26 +00:00
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:
parent
99d9a3d299
commit
f4495de143
@ -180,7 +180,10 @@ impl fmt::Display for ValidationError {
|
||||
CpusMaxLowerThanBoot => write!(f, "Max CPUs lower than boot CPUs"),
|
||||
DiskSocketAndPath => write!(f, "Disk path and vhost socket both provided"),
|
||||
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"),
|
||||
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")
|
||||
}
|
||||
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) => {
|
||||
write!(
|
||||
@ -1756,6 +1762,23 @@ impl VmConfig {
|
||||
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
|
||||
// Returns the list of unique identifiers provided through the
|
||||
// configuration.
|
||||
@ -1800,7 +1823,7 @@ impl VmConfig {
|
||||
if disk.vhost_socket.as_ref().and(disk.path.as_ref()).is_some() {
|
||||
return Err(ValidationError::DiskSocketAndPath);
|
||||
}
|
||||
if disk.vhost_user && !self.memory.shared {
|
||||
if disk.vhost_user && !self.backed_by_shared_memory() {
|
||||
return Err(ValidationError::VhostUserRequiresSharedMemory);
|
||||
}
|
||||
if disk.vhost_user && disk.vhost_socket.is_none() {
|
||||
@ -1815,7 +1838,7 @@ impl VmConfig {
|
||||
|
||||
if let Some(nets) = &self.net {
|
||||
for net in nets {
|
||||
if net.vhost_user && !self.memory.shared {
|
||||
if net.vhost_user && !self.backed_by_shared_memory() {
|
||||
return Err(ValidationError::VhostUserRequiresSharedMemory);
|
||||
}
|
||||
net.validate(self)?;
|
||||
@ -1826,7 +1849,7 @@ impl VmConfig {
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
for fs in fses {
|
||||
@ -1881,7 +1904,7 @@ impl VmConfig {
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -1606,12 +1606,11 @@ impl Vmm {
|
||||
.unwrap()
|
||||
.lock()
|
||||
.unwrap()
|
||||
.memory
|
||||
.shared
|
||||
.backed_by_shared_memory()
|
||||
&& send_data_migration.local
|
||||
{
|
||||
return Err(MigratableError::MigrateSend(anyhow!(
|
||||
"Local migration requires shared memory enabled"
|
||||
"Local migration requires shared memory or hugepages enabled"
|
||||
)));
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user