diff --git a/docs/memory.md b/docs/memory.md index e2252f371..24f6b00ce 100644 --- a/docs/memory.md +++ b/docs/memory.md @@ -112,8 +112,7 @@ _Example_ Amount of memory that can be dynamically added to the VM. -Value is an unsigned integer of 64 bits. A value of 0 simply means that no -memory can be added to the VM. +Value is an unsigned integer of 64 bits. A value of 0 is invalid. _Example_ @@ -149,11 +148,12 @@ struct MemoryZoneConfig { shared: bool, hugepages: bool, host_numa_node: Option, + hotplug_size: Option, } ``` ``` ---memory-zone User defined memory zone parameters "size=,file=,shared=on|off,hugepages=on|off,host_numa_node=,id=" +--memory-zone User defined memory zone parameters "size=,file=,shared=on|off,hugepages=on|off,host_numa_node=,id=,hotplug_size=" ``` This parameter expects one or more occurences, allowing for a list of memory @@ -288,6 +288,21 @@ _Example_ --memory-zone id=mem0,size=1G,host_numa_node=0 ``` +### `hotplug_size` + +Amount of memory that can be dynamically added to the memory zone. Since +`virtio-mem` is the only way of resizing a memory zone, one must specify +the `hotplug_method=virtio-mem` to the `--memory` parameter. + +Value is an unsigned integer of 64 bits. A value of 0 is invalid. + +_Example_ + +``` +--memory size=0,hotplug_method=virtio-mem +--memory-zone id=mem0,size=1G,hotplug_size=1G +``` + ## NUMA settings `NumaConfig` or what is known as `--numa` from the CLI perspective has been diff --git a/src/main.rs b/src/main.rs index 2fe9e5807..aab26c1da 100644 --- a/src/main.rs +++ b/src/main.rs @@ -121,7 +121,7 @@ fn create_app<'a, 'b>( "User defined memory zone parameters \ \"size=,file=,\ shared=on|off,hugepages=on|off,host_numa_node=,\ - id=\"", + id=,hotplug_size=\"", ) .takes_value(true) .min_values(1) diff --git a/vmm/src/api/openapi/cloud-hypervisor.yaml b/vmm/src/api/openapi/cloud-hypervisor.yaml index 0f715a10d..3e07fcd5d 100644 --- a/vmm/src/api/openapi/cloud-hypervisor.yaml +++ b/vmm/src/api/openapi/cloud-hypervisor.yaml @@ -477,6 +477,9 @@ components: host_numa_node: type: integer format: uint32 + hotplug_size: + type: integer + format: int64 MemoryConfig: required: diff --git a/vmm/src/config.rs b/vmm/src/config.rs index 9c865294b..7ca56af71 100644 --- a/vmm/src/config.rs +++ b/vmm/src/config.rs @@ -379,6 +379,8 @@ pub struct MemoryZoneConfig { pub hugepages: bool, #[serde(default)] pub host_numa_node: Option, + #[serde(default)] + pub hotplug_size: Option, } #[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] @@ -460,7 +462,8 @@ impl MemoryConfig { .add("file") .add("shared") .add("hugepages") - .add("host_numa_node"); + .add("host_numa_node") + .add("hotplug_size"); parser.parse(memory_zone).map_err(Error::ParseMemoryZone)?; let id = parser.get("id").ok_or(Error::ParseMemoryZoneIdMissing)?; @@ -483,6 +486,10 @@ impl MemoryConfig { let host_numa_node = parser .convert::("host_numa_node") .map_err(Error::ParseMemoryZone)?; + let hotplug_size = parser + .convert::("hotplug_size") + .map_err(Error::ParseMemoryZone)? + .map(|v| v.0); zones.push(MemoryZoneConfig { id, @@ -491,6 +498,7 @@ impl MemoryConfig { shared, hugepages, host_numa_node, + hotplug_size, }); } Some(zones) diff --git a/vmm/src/memory_manager.rs b/vmm/src/memory_manager.rs index 0d40dd5c4..7481813a0 100644 --- a/vmm/src/memory_manager.rs +++ b/vmm/src/memory_manager.rs @@ -215,6 +215,9 @@ pub enum Error { /// Invalid size for resizing. Can be anything except 0. InvalidHotplugSize, + + /// Invalid hotplug method associated with memory zones resizing capability. + InvalidHotplugMethodWithMemoryZones, } const ENABLE_FLAG: usize = 0; @@ -442,6 +445,7 @@ impl MemoryManager { shared: config.shared, hugepages: config.hugepages, host_numa_node: None, + hotplug_size: config.hotplug_size, }]; (config.size, zones) @@ -472,6 +476,11 @@ impl MemoryManager { ); return Err(Error::InvalidSharedMemoryZoneWithHostNuma); } + + if zone.hotplug_size.is_some() && config.hotplug_method == HotplugMethod::Acpi { + error!("Invalid to set ACPI hotplug method for memory zones"); + return Err(Error::InvalidHotplugMethodWithMemoryZones); + } } (total_ram_size, zones)