diff --git a/src/runtime-rs/crates/hypervisor/Cargo.toml b/src/runtime-rs/crates/hypervisor/Cargo.toml index e413791e7b..46879eb256 100644 --- a/src/runtime-rs/crates/hypervisor/Cargo.toml +++ b/src/runtime-rs/crates/hypervisor/Cargo.toml @@ -35,7 +35,7 @@ kata-types = { path = "../../../libs/kata-types" } logging = { path = "../../../libs/logging" } shim-interface = { path = "../../../libs/shim-interface" } -dragonball = { path = "../../../dragonball", features = ["atomic-guest-memory", "virtio-vsock", "hotplug", "virtio-blk", "virtio-net", "virtio-fs", "vhost-net", "dbs-upcall"] } +dragonball = { path = "../../../dragonball", features = ["atomic-guest-memory", "virtio-vsock", "hotplug", "virtio-blk", "virtio-net", "virtio-fs", "vhost-net", "dbs-upcall","virtio-mem", "virtio-balloon"] } ch-config = { path = "ch-config", optional = true } tests_utils = { path = "../../tests/utils" } diff --git a/src/runtime-rs/crates/hypervisor/src/ch/inner_hypervisor.rs b/src/runtime-rs/crates/hypervisor/src/ch/inner_hypervisor.rs index 85a4ee3fa4..59d97ed2c4 100644 --- a/src/runtime-rs/crates/hypervisor/src/ch/inner_hypervisor.rs +++ b/src/runtime-rs/crates/hypervisor/src/ch/inner_hypervisor.rs @@ -8,8 +8,10 @@ use crate::ch::utils::get_api_socket_path; use crate::ch::utils::get_vsock_path; use crate::kernel_param::KernelParams; use crate::utils::{get_jailer_root, get_sandbox_path}; +use crate::MemoryConfig; +use crate::VM_ROOTFS_DRIVER_BLK; +use crate::VM_ROOTFS_DRIVER_PMEM; use crate::{VcpuThreadIds, VmmState}; -use crate::{VM_ROOTFS_DRIVER_BLK, VM_ROOTFS_DRIVER_PMEM}; use anyhow::{anyhow, Context, Result}; use ch_config::ch_api::{ cloud_hypervisor_vm_create, cloud_hypervisor_vm_start, cloud_hypervisor_vmm_ping, @@ -753,6 +755,14 @@ impl CloudHypervisorInner { pub(crate) fn guest_memory_block_size_mb(&self) -> u32 { todo!() } + + pub(crate) fn resize_memory( + &self, + _req_mem_mb: u32, + _curr_mem_mb: u32, + ) -> Result<(u32, MemoryConfig)> { + todo!() + } } // Log all output from the CH process until a shutdown signal is received. diff --git a/src/runtime-rs/crates/hypervisor/src/ch/mod.rs b/src/runtime-rs/crates/hypervisor/src/ch/mod.rs index 328333b9d9..ff6b062b7b 100644 --- a/src/runtime-rs/crates/hypervisor/src/ch/mod.rs +++ b/src/runtime-rs/crates/hypervisor/src/ch/mod.rs @@ -5,7 +5,7 @@ use super::HypervisorState; use crate::device::DeviceType; -use crate::{Hypervisor, VcpuThreadIds}; +use crate::{Hypervisor, MemoryConfig, VcpuThreadIds}; use anyhow::{Context, Result}; use async_trait::async_trait; use kata_types::capabilities::{Capabilities, CapabilityBits}; @@ -177,6 +177,15 @@ impl Hypervisor for CloudHypervisor { let inner = self.inner.read().await; inner.guest_memory_block_size_mb() } + + async fn resize_memory( + &self, + req_mem_mb: u32, + curr_mem_mb: u32, + ) -> Result<(u32, MemoryConfig)> { + let inner = self.inner.read().await; + inner.resize_memory(req_mem_mb, curr_mem_mb) + } } #[async_trait] diff --git a/src/runtime-rs/crates/hypervisor/src/dragonball/inner.rs b/src/runtime-rs/crates/hypervisor/src/dragonball/inner.rs index 51660f1ba1..3ac87168f5 100644 --- a/src/runtime-rs/crates/hypervisor/src/dragonball/inner.rs +++ b/src/runtime-rs/crates/hypervisor/src/dragonball/inner.rs @@ -6,13 +6,14 @@ use super::vmm_instance::VmmInstance; use crate::{ - device::DeviceType, hypervisor_persist::HypervisorState, kernel_param::KernelParams, VmmState, - DEV_HUGEPAGES, HUGETLBFS, HUGE_SHMEM, HYPERVISOR_DRAGONBALL, SHMEM, + device::DeviceType, hypervisor_persist::HypervisorState, kernel_param::KernelParams, + MemoryConfig, VmmState, DEV_HUGEPAGES, HUGETLBFS, HUGE_SHMEM, HYPERVISOR_DRAGONBALL, SHMEM, }; use anyhow::{anyhow, Context, Result}; use async_trait::async_trait; use dragonball::{ api::v1::{BootSourceConfig, VcpuResizeInfo}, + device_manager::{balloon_dev_mgr::BalloonDeviceConfigInfo, mem_dev_mgr::MemDeviceConfigInfo}, vm::VmConfigInfo, }; @@ -26,6 +27,7 @@ use kata_types::{ }; use nix::mount::MsFlags; use persist::sandbox_persist::Persist; +use std::cmp::Ordering; use std::{collections::HashSet, fs::create_dir_all}; const DRAGONBALL_KERNEL: &str = "vmlinux"; @@ -343,6 +345,64 @@ impl DragonballInner { Ok((old_vcpus, new_vcpus)) } + // curr_mem_m size = default + hotplug + pub(crate) fn resize_memory( + &self, + req_mem_mb: u32, + curr_mem_mb: u32, + ) -> Result<(u32, MemoryConfig)> { + let mem_device_to_insert = match req_mem_mb.cmp(&curr_mem_mb) { + Ordering::Greater => { + // We need to insert a new memory device + let add_mem_mb = req_mem_mb - curr_mem_mb; + if self.config.memory_info.enable_virtio_mem { + Some(MemDeviceConfigInfo { + mem_id: format!("mem{}", curr_mem_mb), + size_mib: add_mem_mb as u64, + capacity_mib: add_mem_mb as u64, + multi_region: false, + host_numa_node_id: None, + guest_numa_node_id: None, + use_shared_irq: None, + use_generic_irq: None, + }) + } else { + None + } + } + Ordering::Less => { + // We need to insert a new balloon device to release memory + let balloon_config = BalloonDeviceConfigInfo { + balloon_id: format!("mem{}", curr_mem_mb), + size_mib: (curr_mem_mb - req_mem_mb) as u64, + use_shared_irq: None, + use_generic_irq: None, + f_deflate_on_oom: false, + f_reporting: false, + }; + self.vmm_instance + .insert_balloon_device(balloon_config) + .context("failed to insert balloon device")?; + None + } + Ordering::Equal => None, // Everything is already set up + }; + + // If we have a memory device to insert, do it now + if let Some(mem_config) = mem_device_to_insert { + self.vmm_instance + .insert_mem_device(mem_config) + .context("failed to insert memory device")?; + } + + Ok(( + req_mem_mb, + MemoryConfig { + ..Default::default() + }, + )) + } + pub fn set_hypervisor_config(&mut self, config: HypervisorConfig) { self.config = config; } @@ -359,7 +419,7 @@ impl DragonballInner { self.guest_memory_block_size_mb = size; } - pub(crate) fn get_guest_memory_block_size(&self) -> u32 { + pub(crate) fn guest_memory_block_size_mb(&self) -> u32 { self.guest_memory_block_size_mb } } diff --git a/src/runtime-rs/crates/hypervisor/src/dragonball/mod.rs b/src/runtime-rs/crates/hypervisor/src/dragonball/mod.rs index 8a59e350a7..3af4acc73d 100644 --- a/src/runtime-rs/crates/hypervisor/src/dragonball/mod.rs +++ b/src/runtime-rs/crates/hypervisor/src/dragonball/mod.rs @@ -26,7 +26,7 @@ use kata_types::config::hypervisor::Hypervisor as HypervisorConfig; use tokio::sync::RwLock; use tracing::instrument; -use crate::{DeviceType, Hypervisor, NetworkConfig, VcpuThreadIds}; +use crate::{DeviceType, Hypervisor, MemoryConfig, NetworkConfig, VcpuThreadIds}; pub struct Dragonball { inner: Arc>, @@ -191,7 +191,16 @@ impl Hypervisor for Dragonball { async fn guest_memory_block_size(&self) -> u32 { let inner = self.inner.read().await; - inner.get_guest_memory_block_size() + inner.guest_memory_block_size_mb() + } + + async fn resize_memory( + &self, + req_mem_mb: u32, + curr_mem_mb: u32, + ) -> Result<(u32, MemoryConfig)> { + let inner = self.inner.read().await; + inner.resize_memory(req_mem_mb, curr_mem_mb) } } diff --git a/src/runtime-rs/crates/hypervisor/src/dragonball/vmm_instance.rs b/src/runtime-rs/crates/hypervisor/src/dragonball/vmm_instance.rs index 4311fdf98d..899f4f258c 100644 --- a/src/runtime-rs/crates/hypervisor/src/dragonball/vmm_instance.rs +++ b/src/runtime-rs/crates/hypervisor/src/dragonball/vmm_instance.rs @@ -19,6 +19,7 @@ use dragonball::{ InstanceInfo, InstanceState, NetworkInterfaceConfig, VcpuResizeInfo, VmmAction, VmmActionError, VmmData, VmmRequest, VmmResponse, VmmService, VsockDeviceConfigInfo, }, + device_manager::{balloon_dev_mgr::BalloonDeviceConfigInfo, mem_dev_mgr::MemDeviceConfigInfo}, vm::VmConfigInfo, Vmm, }; @@ -255,6 +256,18 @@ impl VmmInstance { Ok(()) } + pub fn insert_mem_device(&self, cfg: MemDeviceConfigInfo) -> Result<()> { + self.handle_request(Request::Sync(VmmAction::InsertMemDevice(cfg.clone()))) + .with_context(|| format!("Failed to insert memory device : {:?}", cfg))?; + Ok(()) + } + + pub fn insert_balloon_device(&self, cfg: BalloonDeviceConfigInfo) -> Result<()> { + self.handle_request(Request::Sync(VmmAction::InsertBalloonDevice(cfg.clone()))) + .with_context(|| format!("Failed to insert balloon device: {:?}", cfg))?; + Ok(()) + } + pub fn pause(&self) -> Result<()> { todo!() } diff --git a/src/runtime-rs/crates/hypervisor/src/lib.rs b/src/runtime-rs/crates/hypervisor/src/lib.rs index 3716dff523..9a21530085 100644 --- a/src/runtime-rs/crates/hypervisor/src/lib.rs +++ b/src/runtime-rs/crates/hypervisor/src/lib.rs @@ -73,6 +73,14 @@ pub struct VcpuThreadIds { pub vcpus: HashMap, } +#[derive(Debug, Default)] +pub struct MemoryConfig { + pub slot: u32, + pub size_mb: u32, + pub addr: u64, + pub probe: bool, +} + #[async_trait] pub trait Hypervisor: std::fmt::Debug + Send + Sync { // vm manager @@ -106,4 +114,6 @@ pub trait Hypervisor: std::fmt::Debug + Send + Sync { async fn set_capabilities(&self, flag: CapabilityBits); async fn set_guest_memory_block_size(&self, size: u32); async fn guest_memory_block_size(&self) -> u32; + async fn resize_memory(&self, req_mem_mb: u32, curr_mem_mb: u32) + -> Result<(u32, MemoryConfig)>; } diff --git a/src/runtime-rs/crates/hypervisor/src/qemu/inner.rs b/src/runtime-rs/crates/hypervisor/src/qemu/inner.rs index 18096bfc43..a2ec9704e3 100644 --- a/src/runtime-rs/crates/hypervisor/src/qemu/inner.rs +++ b/src/runtime-rs/crates/hypervisor/src/qemu/inner.rs @@ -5,7 +5,7 @@ use anyhow::Result; -use crate::{HypervisorConfig, VcpuThreadIds}; +use crate::{HypervisorConfig, MemoryConfig, VcpuThreadIds}; use kata_types::capabilities::{Capabilities, CapabilityBits}; const VSOCK_SCHEME: &str = "vsock"; @@ -152,6 +152,14 @@ impl QemuInner { pub(crate) fn guest_memory_block_size_mb(&self) -> u32 { todo!() } + + pub(crate) fn resize_memory( + &self, + _req_mem_mb: u32, + _curr_mem_mb: u32, + ) -> Result<(u32, MemoryConfig)> { + todo!() + } } use crate::device::DeviceType; diff --git a/src/runtime-rs/crates/hypervisor/src/qemu/mod.rs b/src/runtime-rs/crates/hypervisor/src/qemu/mod.rs index 904e582865..afc6786545 100644 --- a/src/runtime-rs/crates/hypervisor/src/qemu/mod.rs +++ b/src/runtime-rs/crates/hypervisor/src/qemu/mod.rs @@ -7,7 +7,7 @@ mod inner; use crate::device::DeviceType; use crate::hypervisor_persist::HypervisorState; -use crate::Hypervisor; +use crate::{Hypervisor, MemoryConfig}; use crate::{HypervisorConfig, VcpuThreadIds}; use inner::QemuInner; use kata_types::capabilities::{Capabilities, CapabilityBits}; @@ -172,4 +172,13 @@ impl Hypervisor for Qemu { let inner = self.inner.read().await; inner.guest_memory_block_size_mb() } + + async fn resize_memory( + &self, + req_mem_mb: u32, + curr_mem_mb: u32, + ) -> Result<(u32, MemoryConfig)> { + let inner = self.inner.read().await; + inner.resize_memory(req_mem_mb, curr_mem_mb) + } }