vmm: Always add virtio-mem region upon VM creation

Now that e820 tables are created from the 'boot_guest_memory', we can
simplify the memory manager code by adding the virtio-mem regions when
they are created. There's no need to wait for the first hotplug to
insert these regions.

This also anticipates the need for starting a VM with some memory
already plugged into the virtio-mem region.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
This commit is contained in:
Sebastien Boeuf 2020-09-14 17:48:13 +02:00
parent 66fc557015
commit 8b5202aa5a
2 changed files with 13 additions and 34 deletions

View File

@ -619,8 +619,9 @@ impl MemoryManager {
Ok(()) Ok(())
})?; })?;
for region in virtio_mem_regions.iter() { for region in virtio_mem_regions.drain(..) {
memory_manager.lock().unwrap().create_userspace_mapping( let mut mm = memory_manager.lock().unwrap();
mm.create_userspace_mapping(
region.start_addr().raw_value(), region.start_addr().raw_value(),
region.len() as u64, region.len() as u64,
region.as_ptr() as u64, region.as_ptr() as u64,
@ -632,6 +633,7 @@ impl MemoryManager {
.unwrap() .unwrap()
.allocate_mmio_addresses(Some(region.start_addr()), region.len(), None) .allocate_mmio_addresses(Some(region.start_addr()), region.len(), None)
.ok_or(Error::MemoryRangeAllocation)?; .ok_or(Error::MemoryRangeAllocation)?;
mm.add_region(region)?;
} }
// Allocate RAM and Reserved address ranges. // Allocate RAM and Reserved address ranges.
@ -1129,12 +1131,8 @@ impl MemoryManager {
Ok(()) Ok(())
} }
pub fn virtio_mem_resize( pub fn virtio_mem_resize(&mut self, id: &str, size: u64) -> Result<(), Error> {
&mut self, if let Some(memory_zone) = self.memory_zones.get_mut(id) {
id: &str,
size: u64,
) -> Result<Option<Arc<GuestRegionMmap>>, Error> {
let virtio_mem_region = if let Some(memory_zone) = self.memory_zones.get_mut(id) {
if let Some(resize) = &memory_zone.virtio_mem_resize { if let Some(resize) = &memory_zone.virtio_mem_resize {
resize.work(size).map_err(Error::VirtioMemResizeFail)?; resize.work(size).map_err(Error::VirtioMemResizeFail)?;
} else { } else {
@ -1142,18 +1140,11 @@ impl MemoryManager {
return Err(Error::MissingVirtioMemHandler); return Err(Error::MissingVirtioMemHandler);
} }
memory_zone.virtio_mem_region.take() return Ok(());
} else {
error!("Failed resizing virtio-mem region: Unknown memory zone");
return Err(Error::UnknownMemoryZone);
};
// Add the region if that's the first time we resize.
if let Some(region) = virtio_mem_region.clone() {
self.add_region(region)?;
} }
Ok(virtio_mem_region) error!("Failed resizing virtio-mem region: Unknown memory zone");
Err(Error::UnknownMemoryZone)
} }
pub fn balloon_resize(&mut self, expected_ram: u64) -> Result<u64, Error> { pub fn balloon_resize(&mut self, expected_ram: u64) -> Result<u64, Error> {
@ -1189,8 +1180,7 @@ impl MemoryManager {
match self.hotplug_method { match self.hotplug_method {
HotplugMethod::VirtioMem => { HotplugMethod::VirtioMem => {
if desired_ram >= self.boot_ram { if desired_ram >= self.boot_ram {
region = self.virtio_mem_resize(DEFAULT_MEMORY_ZONE, desired_ram - self.boot_ram)?;
self.virtio_mem_resize(DEFAULT_MEMORY_ZONE, desired_ram - self.boot_ram)?;
self.current_ram = desired_ram; self.current_ram = desired_ram;
} }
} }
@ -1210,7 +1200,7 @@ impl MemoryManager {
id: &str, id: &str,
desired_ram: u64, desired_ram: u64,
config: &MemoryConfig, config: &MemoryConfig,
) -> Result<Option<Arc<GuestRegionMmap>>, Error> { ) -> Result<(), Error> {
if !self.user_provided_zones { if !self.user_provided_zones {
error!( error!(
"Not allowed to resize guest memory zone when no zone is \ "Not allowed to resize guest memory zone when no zone is \

View File

@ -925,22 +925,11 @@ impl Vm {
} }
pub fn resize_zone(&mut self, id: String, desired_memory: u64) -> Result<()> { pub fn resize_zone(&mut self, id: String, desired_memory: u64) -> Result<()> {
let new_region = self self.memory_manager
.memory_manager
.lock() .lock()
.unwrap() .unwrap()
.resize_zone(&id, desired_memory, &self.config.lock().unwrap().memory) .resize_zone(&id, desired_memory, &self.config.lock().unwrap().memory)
.map_err(Error::MemoryManager)?; .map_err(Error::MemoryManager)
if let Some(new_region) = &new_region {
self.device_manager
.lock()
.unwrap()
.update_memory(&new_region)
.map_err(Error::DeviceManager)?;
}
Ok(())
} }
#[cfg(not(feature = "pci_support"))] #[cfg(not(feature = "pci_support"))]