mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2025-02-22 11:22:26 +00:00
vmm: Update memory configuration upon virtio-mem resizing
Based on all the preparatory work achieved through previous commits, this patch updates the 'hotplugged_size' field for both MemoryConfig and MemoryZoneConfig structures when either the whole memory is resized, or simply when a memory zone is resized. This fixes the lack of support for rebooting a VM with the right amount of memory plugged in. Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
This commit is contained in:
parent
de2b917f55
commit
1e1a50ef70
@ -664,8 +664,8 @@ impl MemoryManager {
|
||||
mergeable: config.mergeable,
|
||||
allocator: allocator.clone(),
|
||||
hotplug_method: config.hotplug_method.clone(),
|
||||
boot_ram: config.size,
|
||||
current_ram: config.size,
|
||||
boot_ram: ram_size,
|
||||
current_ram: ram_size,
|
||||
next_hotplug_slot: 0,
|
||||
snapshot: Mutex::new(None),
|
||||
shared: config.shared,
|
||||
@ -1268,12 +1268,7 @@ impl MemoryManager {
|
||||
Ok(region)
|
||||
}
|
||||
|
||||
pub fn resize_zone(
|
||||
&mut self,
|
||||
id: &str,
|
||||
desired_ram: u64,
|
||||
config: &MemoryConfig,
|
||||
) -> Result<(), Error> {
|
||||
pub fn resize_zone(&mut self, id: &str, virtio_mem_size: u64) -> Result<(), Error> {
|
||||
if !self.user_provided_zones {
|
||||
error!(
|
||||
"Not allowed to resize guest memory zone when no zone is \
|
||||
@ -1282,25 +1277,7 @@ impl MemoryManager {
|
||||
return Err(Error::ResizeZone);
|
||||
}
|
||||
|
||||
if let Some(zones) = &config.zones {
|
||||
for zone in zones.iter() {
|
||||
if zone.id == id {
|
||||
if desired_ram >= zone.size {
|
||||
return self.virtio_mem_resize(id, desired_ram - zone.size);
|
||||
} else {
|
||||
error!(
|
||||
"Invalid to ask less ({}) than boot RAM ({}) for \
|
||||
this memory zone",
|
||||
desired_ram, zone.size,
|
||||
);
|
||||
return Err(Error::ResizeZone);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
error!("Could not find the memory zone {} for the resize", id);
|
||||
Err(Error::ResizeZone)
|
||||
self.virtio_mem_resize(id, virtio_mem_size)
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
|
@ -209,6 +209,9 @@ pub enum Error {
|
||||
|
||||
/// Cannot apply seccomp filter
|
||||
ApplySeccompFilter(seccomp::Error),
|
||||
|
||||
/// Failed resizing a memory zone.
|
||||
ResizeZone,
|
||||
}
|
||||
pub type Result<T> = result::Result<T, Error>;
|
||||
|
||||
@ -884,6 +887,8 @@ impl Vm {
|
||||
.resize(desired_memory)
|
||||
.map_err(Error::MemoryManager)?;
|
||||
|
||||
let mut memory_config = &mut self.config.lock().unwrap().memory;
|
||||
|
||||
if let Some(new_region) = &new_region {
|
||||
self.device_manager
|
||||
.lock()
|
||||
@ -891,7 +896,6 @@ impl Vm {
|
||||
.update_memory(&new_region)
|
||||
.map_err(Error::DeviceManager)?;
|
||||
|
||||
let memory_config = &self.config.lock().unwrap().memory;
|
||||
match memory_config.hotplug_method {
|
||||
HotplugMethod::Acpi => {
|
||||
self.device_manager
|
||||
@ -907,7 +911,16 @@ impl Vm {
|
||||
// We update the VM config regardless of the actual guest resize
|
||||
// operation result (happened or not), so that if the VM reboots
|
||||
// it will be running with the last configure memory size.
|
||||
self.config.lock().unwrap().memory.size = desired_memory;
|
||||
match memory_config.hotplug_method {
|
||||
HotplugMethod::Acpi => memory_config.size = desired_memory,
|
||||
HotplugMethod::VirtioMem => {
|
||||
if desired_memory > memory_config.size {
|
||||
memory_config.hotplugged_size = Some(desired_memory - memory_config.size);
|
||||
} else {
|
||||
memory_config.hotplugged_size = None;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(desired_ram_w_balloon) = desired_ram_w_balloon {
|
||||
@ -925,11 +938,39 @@ impl Vm {
|
||||
}
|
||||
|
||||
pub fn resize_zone(&mut self, id: String, desired_memory: u64) -> Result<()> {
|
||||
self.memory_manager
|
||||
.lock()
|
||||
.unwrap()
|
||||
.resize_zone(&id, desired_memory, &self.config.lock().unwrap().memory)
|
||||
.map_err(Error::MemoryManager)
|
||||
let memory_config = &mut self.config.lock().unwrap().memory;
|
||||
|
||||
if let Some(zones) = &mut memory_config.zones {
|
||||
for zone in zones.iter_mut() {
|
||||
if zone.id == id {
|
||||
if desired_memory >= zone.size {
|
||||
let hotplugged_size = desired_memory - zone.size;
|
||||
self.memory_manager
|
||||
.lock()
|
||||
.unwrap()
|
||||
.resize_zone(&id, desired_memory - zone.size)
|
||||
.map_err(Error::MemoryManager)?;
|
||||
// We update the memory zone config regardless of the
|
||||
// actual 'resize-zone' operation result (happened or
|
||||
// not), so that if the VM reboots it will be running
|
||||
// with the last configured memory zone size.
|
||||
zone.hotplugged_size = Some(hotplugged_size);
|
||||
|
||||
return Ok(());
|
||||
} else {
|
||||
error!(
|
||||
"Invalid to ask less ({}) than boot RAM ({}) for \
|
||||
this memory zone",
|
||||
desired_memory, zone.size,
|
||||
);
|
||||
return Err(Error::ResizeZone);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
error!("Could not find the memory zone {} for the resize", id);
|
||||
Err(Error::ResizeZone)
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "pci_support"))]
|
||||
|
Loading…
x
Reference in New Issue
Block a user