mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2026-08-05 02:19:16 +00:00
vmm: Allow receiving information about changing MemoryZones
It is possible to migrate a VM to a host that might have a different but compatible NUMA configuration. For example, it should be possible to move a `MemoryZone` from NUMA node 2 and 3 of the sender to nodes 0 and 1 on the receiver, given sender and receiver nodes are compatible with respect to available memory. In such a case, we need to adjust the mapping of guest memory to host nodes. We need this information for live migration as well as for snapshot (when performing cold migration). We consume this information in the following commit. Signed-off-by: Pascal Scholz <pascal.scholz@cyberus-technology.de> On-behalf-of: SAP pascal.scholz@sap.com
This commit is contained in:
committed by
Rob Bradford
parent
febe70ae36
commit
c2da8fed8e
@@ -54,7 +54,9 @@ use vmm_sys_util::eventfd::EventFd;
|
||||
pub use self::dbus::start_dbus_thread;
|
||||
pub use self::http::{start_http_fd_thread, start_http_path_thread};
|
||||
use crate::Error as VmmError;
|
||||
use crate::config::{RestoreConfig, RestoredVfioConfig, deserialize_restored_fd};
|
||||
use crate::config::{
|
||||
RestoreConfig, RestoredVfioConfig, VmMemoryZoneUpdateData, deserialize_restored_fd,
|
||||
};
|
||||
use crate::device_tree::DeviceTree;
|
||||
use crate::migration::transport::{
|
||||
MAX_MIGRATION_CONNECTIONS, TcpAddressParseError, tcp_address_to_server_name,
|
||||
@@ -319,6 +321,9 @@ pub struct VmReceiveMigrationData {
|
||||
// FDs are not serialized and any deserialized value is invalid; see NetConfig::fds.
|
||||
#[serde(default, deserialize_with = "deserialize_restored_fd")]
|
||||
pub iommufd_fd: Option<i32>,
|
||||
/// Optional memory zone update data
|
||||
#[serde(default)]
|
||||
pub zone_updates: Vec<VmMemoryZoneUpdateData>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
@@ -381,6 +386,7 @@ impl VmReceiveMigrationData {
|
||||
memory_mode,
|
||||
vfio_fds,
|
||||
iommufd_fd,
|
||||
zone_updates: vec![],
|
||||
};
|
||||
|
||||
data.validate()?;
|
||||
@@ -2089,6 +2095,7 @@ mod unit_tests {
|
||||
memory_mode: MigrationMode::Precopy,
|
||||
vfio_fds: None,
|
||||
iommufd_fd: None,
|
||||
zone_updates: vec![],
|
||||
}
|
||||
);
|
||||
|
||||
@@ -2118,6 +2125,7 @@ mod unit_tests {
|
||||
memory_mode: MigrationMode::Precopy,
|
||||
vfio_fds: None,
|
||||
iommufd_fd: None,
|
||||
zone_updates: vec![],
|
||||
}
|
||||
);
|
||||
|
||||
@@ -2143,6 +2151,7 @@ mod unit_tests {
|
||||
memory_mode: MigrationMode::Precopy,
|
||||
vfio_fds: None,
|
||||
iommufd_fd: None,
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
|
||||
@@ -2158,6 +2167,7 @@ mod unit_tests {
|
||||
memory_mode: MigrationMode::Postcopy,
|
||||
vfio_fds: None,
|
||||
iommufd_fd: None,
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
@@ -2808,6 +2808,15 @@ impl FromStr for MemoryRestoreMode {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Deserialize, Serialize, Debug, Eq, PartialEq)]
|
||||
/// Data required for updating memory zone <-> host NUMA node mappings.
|
||||
pub struct VmMemoryZoneUpdateData {
|
||||
/// Id of the MemoryZone to update
|
||||
pub id: String,
|
||||
/// Host NUMA node to relocate the MemoryZone to
|
||||
pub host_numa_node: u32,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize, Default)]
|
||||
pub struct RestoredVfioConfig {
|
||||
pub id: String,
|
||||
@@ -2844,6 +2853,8 @@ pub struct RestoreConfig {
|
||||
pub iommufd_fd: Option<i32>,
|
||||
#[serde(default)]
|
||||
pub resume: bool,
|
||||
#[serde(default)]
|
||||
pub zone_updates: Vec<VmMemoryZoneUpdateData>,
|
||||
}
|
||||
|
||||
impl RestoreConfig {
|
||||
@@ -2928,6 +2939,7 @@ impl RestoreConfig {
|
||||
vfio_fds,
|
||||
iommufd_fd,
|
||||
resume,
|
||||
zone_updates: vec![],
|
||||
})
|
||||
}
|
||||
|
||||
@@ -5196,6 +5208,7 @@ id=\"{id}\",pci_segment={pci_segment},queue_sizes={queue_sizes}"
|
||||
vfio_fds: None,
|
||||
iommufd_fd: None,
|
||||
resume: false,
|
||||
zone_updates: vec![],
|
||||
}
|
||||
);
|
||||
assert_eq!(
|
||||
@@ -5221,6 +5234,7 @@ id=\"{id}\",pci_segment={pci_segment},queue_sizes={queue_sizes}"
|
||||
vfio_fds: None,
|
||||
iommufd_fd: None,
|
||||
resume: false,
|
||||
zone_updates: vec![],
|
||||
}
|
||||
);
|
||||
assert_eq!(
|
||||
@@ -5233,6 +5247,7 @@ id=\"{id}\",pci_segment={pci_segment},queue_sizes={queue_sizes}"
|
||||
vfio_fds: None,
|
||||
iommufd_fd: None,
|
||||
resume: false,
|
||||
zone_updates: vec![],
|
||||
}
|
||||
);
|
||||
assert_eq!(
|
||||
@@ -5245,6 +5260,7 @@ id=\"{id}\",pci_segment={pci_segment},queue_sizes={queue_sizes}"
|
||||
vfio_fds: None,
|
||||
iommufd_fd: None,
|
||||
resume: true,
|
||||
zone_updates: vec![],
|
||||
}
|
||||
);
|
||||
assert_eq!(
|
||||
@@ -5268,6 +5284,7 @@ id=\"{id}\",pci_segment={pci_segment},queue_sizes={queue_sizes}"
|
||||
]),
|
||||
iommufd_fd: Some(7),
|
||||
resume: false,
|
||||
zone_updates: vec![],
|
||||
}
|
||||
);
|
||||
// Parsing should fail as source_url is a required field
|
||||
@@ -5382,6 +5399,7 @@ id=\"{id}\",pci_segment={pci_segment},queue_sizes={queue_sizes}"
|
||||
vfio_fds: None,
|
||||
iommufd_fd: None,
|
||||
resume: false,
|
||||
zone_updates: vec![],
|
||||
};
|
||||
valid_config.validate(&snapshot_vm_config).unwrap();
|
||||
|
||||
@@ -5449,6 +5467,7 @@ id=\"{id}\",pci_segment={pci_segment},queue_sizes={queue_sizes}"
|
||||
vfio_fds: None,
|
||||
iommufd_fd: None,
|
||||
resume: false,
|
||||
zone_updates: vec![],
|
||||
};
|
||||
snapshot_vm_config.net = Some(vec![NetConfig {
|
||||
pci_common: PciDeviceCommonConfig {
|
||||
@@ -5468,6 +5487,7 @@ id=\"{id}\",pci_segment={pci_segment},queue_sizes={queue_sizes}"
|
||||
vfio_fds: None,
|
||||
iommufd_fd: None,
|
||||
resume: false,
|
||||
zone_updates: vec![],
|
||||
};
|
||||
assert_eq!(
|
||||
invalid_restore_mode.validate(&snapshot_vm_config),
|
||||
@@ -5541,6 +5561,7 @@ id=\"{id}\",pci_segment={pci_segment},queue_sizes={queue_sizes}"
|
||||
}]),
|
||||
iommufd_fd: Some(6),
|
||||
resume: false,
|
||||
zone_updates: vec![],
|
||||
};
|
||||
valid_config.validate(&snapshot_vm_config).unwrap();
|
||||
|
||||
|
||||
@@ -3082,9 +3082,10 @@ impl RequestHandler for Vmm {
|
||||
.map_err(MigratableError::MigrateReceive)?;
|
||||
|
||||
info!(
|
||||
"Receiving migration: receiver_url={},tls={}",
|
||||
"Receiving migration: receiver_url={},tls={},zone_updates={:?}",
|
||||
receive_data_migration.receiver_url,
|
||||
receive_data_migration.tls_dir.is_some()
|
||||
receive_data_migration.tls_dir.is_some(),
|
||||
receive_data_migration.zone_updates,
|
||||
);
|
||||
|
||||
let mut listener = transport::receive_migration_listener(
|
||||
@@ -3927,6 +3928,7 @@ mod unit_tests {
|
||||
memory_mode: MigrationMode::default(),
|
||||
vfio_fds,
|
||||
iommufd_fd,
|
||||
zone_updates: vec![],
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user