mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-07-17 17:02:42 +00:00
runtime-rs: check the update memory size
check the update memory size greater than default max memory size Fixes:#6875 Signed-off-by: Zhongtao Hu <zhongtaohu.tim@linux.alibaba.com>
This commit is contained in:
parent
6039417104
commit
9a37e77f2a
@ -14,7 +14,7 @@ edition = "2018"
|
|||||||
bitmask-enum = "2.1.0"
|
bitmask-enum = "2.1.0"
|
||||||
anyhow = "1.0"
|
anyhow = "1.0"
|
||||||
base64 = "0.13.0"
|
base64 = "0.13.0"
|
||||||
byte-unit = "3.1.4"
|
byte-unit = "5.0.3"
|
||||||
glob = "0.3.0"
|
glob = "0.3.0"
|
||||||
lazy_static = "1.4.0"
|
lazy_static = "1.4.0"
|
||||||
num_cpus = "1.13.1"
|
num_cpus = "1.13.1"
|
||||||
@ -26,6 +26,7 @@ serde_json = "1.0.73"
|
|||||||
thiserror = "1.0"
|
thiserror = "1.0"
|
||||||
toml = "0.5.8"
|
toml = "0.5.8"
|
||||||
serde-enum-str = "0.4"
|
serde-enum-str = "0.4"
|
||||||
|
sysinfo = "0.29.11"
|
||||||
|
|
||||||
oci = { path = "../oci" }
|
oci = { path = "../oci" }
|
||||||
safe-path = { path = "../safe-path" }
|
safe-path = { path = "../safe-path" }
|
||||||
|
@ -705,10 +705,10 @@ impl Annotation {
|
|||||||
}
|
}
|
||||||
// Hypervisor Memory related annotations
|
// Hypervisor Memory related annotations
|
||||||
KATA_ANNO_CFG_HYPERVISOR_DEFAULT_MEMORY => {
|
KATA_ANNO_CFG_HYPERVISOR_DEFAULT_MEMORY => {
|
||||||
match byte_unit::Byte::from_str(value) {
|
match byte_unit::Byte::parse_str(value,true) {
|
||||||
Ok(mem_bytes) => {
|
Ok(mem_bytes) => {
|
||||||
let memory_size = mem_bytes
|
let memory_size = mem_bytes
|
||||||
.get_adjusted_unit(byte_unit::ByteUnit::MiB)
|
.get_adjusted_unit(byte_unit::Unit::MiB)
|
||||||
.get_value()
|
.get_value()
|
||||||
as u32;
|
as u32;
|
||||||
info!(sl!(), "get mem {} from annotations: {}", memory_size, value);
|
info!(sl!(), "get mem {} from annotations: {}", memory_size, value);
|
||||||
|
@ -20,7 +20,7 @@ pub enum CapabilityBits {
|
|||||||
/// hypervisor supports hybrid-vsock
|
/// hypervisor supports hybrid-vsock
|
||||||
HybridVsockSupport,
|
HybridVsockSupport,
|
||||||
/// hypervisor supports memory hotplug probe interface
|
/// hypervisor supports memory hotplug probe interface
|
||||||
GuestMemoryHotplugProbe,
|
GuestMemoryProbe,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Capabilities describe a virtcontainers hypervisor capabilities through a bit mask.
|
/// Capabilities describe a virtcontainers hypervisor capabilities through a bit mask.
|
||||||
@ -81,7 +81,7 @@ impl Capabilities {
|
|||||||
|
|
||||||
/// is_mem_hotplug_probe_supported tells if the hypervisor supports hotplug probe interface
|
/// is_mem_hotplug_probe_supported tells if the hypervisor supports hotplug probe interface
|
||||||
pub fn is_mem_hotplug_probe_supported(&self) -> bool {
|
pub fn is_mem_hotplug_probe_supported(&self) -> bool {
|
||||||
self.flags.and(CapabilityBits::GuestMemoryHotplugProbe) != 0
|
self.flags.and(CapabilityBits::GuestMemoryProbe) != 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -130,7 +130,7 @@ mod tests {
|
|||||||
cap.set(CapabilityBits::HybridVsockSupport);
|
cap.set(CapabilityBits::HybridVsockSupport);
|
||||||
assert!(cap.is_hybrid_vsock_supported());
|
assert!(cap.is_hybrid_vsock_supported());
|
||||||
// test append capabilities
|
// test append capabilities
|
||||||
cap.add(CapabilityBits::GuestMemoryHotplugProbe);
|
cap.add(CapabilityBits::GuestMemoryProbe);
|
||||||
assert!(cap.is_mem_hotplug_probe_supported());
|
assert!(cap.is_mem_hotplug_probe_supported());
|
||||||
assert!(cap.is_fs_sharing_supported());
|
assert!(cap.is_fs_sharing_supported());
|
||||||
}
|
}
|
||||||
|
@ -22,18 +22,18 @@
|
|||||||
//! part and common part. But the Kata 2.0 has adopted a policy to build a superset for all
|
//! part and common part. But the Kata 2.0 has adopted a policy to build a superset for all
|
||||||
//! hypervisors, so let's contain it...
|
//! hypervisors, so let's contain it...
|
||||||
|
|
||||||
|
use super::{default, ConfigOps, ConfigPlugin, TomlConfig};
|
||||||
|
use crate::annotations::KATA_ANNO_CFG_HYPERVISOR_PREFIX;
|
||||||
|
use crate::{eother, resolve_path, sl, validate_path};
|
||||||
|
use byte_unit::{Byte, Unit};
|
||||||
|
use lazy_static::lazy_static;
|
||||||
|
use regex::RegexSet;
|
||||||
|
use serde_enum_str::{Deserialize_enum_str, Serialize_enum_str};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::io::{self, Result};
|
use std::io::{self, Result};
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
|
use sysinfo::{System, SystemExt};
|
||||||
use lazy_static::lazy_static;
|
|
||||||
use regex::RegexSet;
|
|
||||||
use serde_enum_str::{Deserialize_enum_str, Serialize_enum_str};
|
|
||||||
|
|
||||||
use super::{default, ConfigOps, ConfigPlugin, TomlConfig};
|
|
||||||
use crate::annotations::KATA_ANNO_CFG_HYPERVISOR_PREFIX;
|
|
||||||
use crate::{eother, resolve_path, sl, validate_path};
|
|
||||||
|
|
||||||
mod dragonball;
|
mod dragonball;
|
||||||
pub use self::dragonball::{DragonballConfig, HYPERVISOR_NAME_DRAGONBALL};
|
pub use self::dragonball::{DragonballConfig, HYPERVISOR_NAME_DRAGONBALL};
|
||||||
@ -586,6 +586,13 @@ pub struct MemoryInfo {
|
|||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub default_memory: u32,
|
pub default_memory: u32,
|
||||||
|
|
||||||
|
/// Default maximum memory in MiB per SB / VM
|
||||||
|
/// unspecified or == 0 --> will be set to the actual amount of physical RAM
|
||||||
|
/// > 0 <= amount of physical RAM --> will be set to the specified number
|
||||||
|
/// > amount of physical RAM --> will be set to the actual amount of physical RAM
|
||||||
|
#[serde(default)]
|
||||||
|
pub default_maxmemory: u32,
|
||||||
|
|
||||||
/// Default memory slots per SB/VM.
|
/// Default memory slots per SB/VM.
|
||||||
///
|
///
|
||||||
/// This is will determine the times that memory will be hotadded to sandbox/VM.
|
/// This is will determine the times that memory will be hotadded to sandbox/VM.
|
||||||
@ -653,13 +660,6 @@ pub struct MemoryInfo {
|
|||||||
/// If swap_in_bytes and memory_limit_in_bytes is not set, the size should be default_memory.
|
/// If swap_in_bytes and memory_limit_in_bytes is not set, the size should be default_memory.
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub enable_guest_swap: bool,
|
pub enable_guest_swap: bool,
|
||||||
|
|
||||||
/// Default maximum memory in MiB per SB / VM
|
|
||||||
/// unspecified or == 0 --> will be set to the actual amount of physical RAM
|
|
||||||
/// > 0 <= amount of physical RAM --> will be set to the specified number
|
|
||||||
/// > amount of physical RAM --> will be set to the actual amount of physical RAM
|
|
||||||
#[serde(default)]
|
|
||||||
pub default_maxmemory: u32,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MemoryInfo {
|
impl MemoryInfo {
|
||||||
@ -669,6 +669,12 @@ impl MemoryInfo {
|
|||||||
self.file_mem_backend,
|
self.file_mem_backend,
|
||||||
"Memory backend file {} is invalid: {}"
|
"Memory backend file {} is invalid: {}"
|
||||||
)?;
|
)?;
|
||||||
|
if self.default_maxmemory == 0 {
|
||||||
|
let s = System::new_all();
|
||||||
|
self.default_maxmemory = Byte::from_u64(s.total_memory())
|
||||||
|
.get_adjusted_unit(Unit::MiB)
|
||||||
|
.get_value() as u32;
|
||||||
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
107
src/runtime-rs/Cargo.lock
generated
107
src/runtime-rs/Cargo.lock
generated
@ -372,12 +372,6 @@ version = "3.13.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1"
|
checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "byte-unit"
|
|
||||||
version = "3.1.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "415301c9de11005d4b92193c0eb7ac7adc37e5a49e0ac9bed0a42343512744b8"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "byte-unit"
|
name = "byte-unit"
|
||||||
version = "4.0.19"
|
version = "4.0.19"
|
||||||
@ -388,6 +382,17 @@ dependencies = [
|
|||||||
"utf8-width",
|
"utf8-width",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "byte-unit"
|
||||||
|
version = "5.0.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bc40af92e0f7f964b7ab1ebc81315cce78fc484802d534143321c956f58d7be3"
|
||||||
|
dependencies = [
|
||||||
|
"rust_decimal",
|
||||||
|
"serde",
|
||||||
|
"utf8-width",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "byteorder"
|
name = "byteorder"
|
||||||
version = "1.4.3"
|
version = "1.4.3"
|
||||||
@ -601,6 +606,30 @@ dependencies = [
|
|||||||
"crossbeam-utils",
|
"crossbeam-utils",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crossbeam-deque"
|
||||||
|
version = "0.8.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if 1.0.0",
|
||||||
|
"crossbeam-epoch",
|
||||||
|
"crossbeam-utils",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crossbeam-epoch"
|
||||||
|
version = "0.9.15"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
"cfg-if 1.0.0",
|
||||||
|
"crossbeam-utils",
|
||||||
|
"memoffset 0.9.0",
|
||||||
|
"scopeguard",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crossbeam-utils"
|
name = "crossbeam-utils"
|
||||||
version = "0.8.16"
|
version = "0.8.16"
|
||||||
@ -1657,7 +1686,7 @@ dependencies = [
|
|||||||
"anyhow",
|
"anyhow",
|
||||||
"base64 0.13.1",
|
"base64 0.13.1",
|
||||||
"bitmask-enum",
|
"bitmask-enum",
|
||||||
"byte-unit 3.1.4",
|
"byte-unit 5.0.3",
|
||||||
"glob",
|
"glob",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"num_cpus",
|
"num_cpus",
|
||||||
@ -1669,6 +1698,7 @@ dependencies = [
|
|||||||
"serde_json",
|
"serde_json",
|
||||||
"slog",
|
"slog",
|
||||||
"slog-scope",
|
"slog-scope",
|
||||||
|
"sysinfo",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"toml 0.5.11",
|
"toml 0.5.11",
|
||||||
]
|
]
|
||||||
@ -1843,6 +1873,15 @@ dependencies = [
|
|||||||
"autocfg",
|
"autocfg",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "memoffset"
|
||||||
|
version = "0.9.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mime"
|
name = "mime"
|
||||||
version = "0.3.17"
|
version = "0.3.17"
|
||||||
@ -2023,6 +2062,15 @@ dependencies = [
|
|||||||
"static_assertions",
|
"static_assertions",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ntapi"
|
||||||
|
version = "0.4.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e8a3895c6391c39d7fe7ebc444a87eb2991b2a0bc718fdabd071eec617fc68e4"
|
||||||
|
dependencies = [
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nu-ansi-term"
|
name = "nu-ansi-term"
|
||||||
version = "0.46.0"
|
version = "0.46.0"
|
||||||
@ -2809,6 +2857,26 @@ dependencies = [
|
|||||||
"rand_core 0.5.1",
|
"rand_core 0.5.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rayon"
|
||||||
|
version = "1.8.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9c27db03db7734835b3f53954b534c91069375ce6ccaa2e065441e07d9b6cdb1"
|
||||||
|
dependencies = [
|
||||||
|
"either",
|
||||||
|
"rayon-core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rayon-core"
|
||||||
|
version = "1.12.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5ce3fb6ad83f861aac485e76e1985cd109d9a3713802152be56c3b1f0e0658ed"
|
||||||
|
dependencies = [
|
||||||
|
"crossbeam-deque",
|
||||||
|
"crossbeam-utils",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rdrand"
|
name = "rdrand"
|
||||||
version = "0.4.0"
|
version = "0.4.0"
|
||||||
@ -3024,6 +3092,16 @@ dependencies = [
|
|||||||
"ordered-multimap",
|
"ordered-multimap",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rust_decimal"
|
||||||
|
version = "1.33.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "06676aec5ccb8fc1da723cc8c0f9a46549f21ebb8753d3915c6c41db1e7f1dc4"
|
||||||
|
dependencies = [
|
||||||
|
"arrayvec",
|
||||||
|
"num-traits",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustc-demangle"
|
name = "rustc-demangle"
|
||||||
version = "0.1.23"
|
version = "0.1.23"
|
||||||
@ -3559,6 +3637,21 @@ dependencies = [
|
|||||||
"unicode-ident",
|
"unicode-ident",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sysinfo"
|
||||||
|
version = "0.29.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cd727fc423c2060f6c92d9534cef765c65a6ed3f428a03d7def74a8c4348e666"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if 1.0.0",
|
||||||
|
"core-foundation-sys",
|
||||||
|
"libc",
|
||||||
|
"ntapi",
|
||||||
|
"once_cell",
|
||||||
|
"rayon",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "take_mut"
|
name = "take_mut"
|
||||||
version = "0.2.2"
|
version = "0.2.2"
|
||||||
|
@ -756,7 +756,7 @@ impl CloudHypervisorInner {
|
|||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn resize_memory(&self, _req_mem_mb: u32) -> Result<(u32, MemoryConfig)> {
|
pub(crate) fn resize_memory(&self, _new_mem_mb: u32) -> Result<(u32, MemoryConfig)> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -178,9 +178,9 @@ impl Hypervisor for CloudHypervisor {
|
|||||||
inner.guest_memory_block_size_mb()
|
inner.guest_memory_block_size_mb()
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn resize_memory(&self, req_mem_mb: u32) -> Result<(u32, MemoryConfig)> {
|
async fn resize_memory(&self, new_mem_mb: u32) -> Result<(u32, MemoryConfig)> {
|
||||||
let inner = self.inner.read().await;
|
let inner = self.inner.read().await;
|
||||||
inner.resize_memory(req_mem_mb)
|
inner.resize_memory(new_mem_mb)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,7 +32,8 @@ use std::{collections::HashSet, fs::create_dir_all};
|
|||||||
|
|
||||||
const DRAGONBALL_KERNEL: &str = "vmlinux";
|
const DRAGONBALL_KERNEL: &str = "vmlinux";
|
||||||
const DRAGONBALL_ROOT_FS: &str = "rootfs";
|
const DRAGONBALL_ROOT_FS: &str = "rootfs";
|
||||||
|
const BALLOON_DEVICE_ID: &str = "balloon0";
|
||||||
|
const MEM_DEVICE_ID: &str = "memmr0";
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct DragonballInner {
|
pub struct DragonballInner {
|
||||||
/// sandbox id
|
/// sandbox id
|
||||||
@ -76,6 +77,9 @@ pub struct DragonballInner {
|
|||||||
|
|
||||||
/// the hotplug memory size
|
/// the hotplug memory size
|
||||||
pub(crate) mem_hotplug_size_mb: u32,
|
pub(crate) mem_hotplug_size_mb: u32,
|
||||||
|
|
||||||
|
/// the balloon size
|
||||||
|
pub(crate) balloon_size: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DragonballInner {
|
impl DragonballInner {
|
||||||
@ -85,7 +89,8 @@ impl DragonballInner {
|
|||||||
CapabilityBits::BlockDeviceSupport
|
CapabilityBits::BlockDeviceSupport
|
||||||
| CapabilityBits::BlockDeviceHotplugSupport
|
| CapabilityBits::BlockDeviceHotplugSupport
|
||||||
| CapabilityBits::FsSharingSupport
|
| CapabilityBits::FsSharingSupport
|
||||||
| CapabilityBits::HybridVsockSupport,
|
| CapabilityBits::HybridVsockSupport
|
||||||
|
| CapabilityBits::GuestMemoryProbe,
|
||||||
);
|
);
|
||||||
DragonballInner {
|
DragonballInner {
|
||||||
id: "".to_string(),
|
id: "".to_string(),
|
||||||
@ -102,6 +107,7 @@ impl DragonballInner {
|
|||||||
capabilities,
|
capabilities,
|
||||||
guest_memory_block_size_mb: 0,
|
guest_memory_block_size_mb: 0,
|
||||||
mem_hotplug_size_mb: 0,
|
mem_hotplug_size_mb: 0,
|
||||||
|
balloon_size: 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -349,13 +355,30 @@ impl DragonballInner {
|
|||||||
Ok((old_vcpus, new_vcpus))
|
Ok((old_vcpus, new_vcpus))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn resize_memory(&mut self, req_mem_mb: u32) -> Result<(u32, MemoryConfig)> {
|
pub(crate) fn resize_memory(&mut self, new_mem_mb: u32) -> Result<(u32, MemoryConfig)> {
|
||||||
|
// check the invalid request memory
|
||||||
|
if new_mem_mb > self.hypervisor_config().memory_info.default_maxmemory {
|
||||||
|
warn!(
|
||||||
|
sl!(),
|
||||||
|
"memory size unchanged, the request memory size {} is greater than the max memory size {}",
|
||||||
|
new_mem_mb, self.hypervisor_config().memory_info.default_maxmemory
|
||||||
|
);
|
||||||
|
|
||||||
|
return Ok((
|
||||||
|
0,
|
||||||
|
MemoryConfig {
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
let had_mem_mb = self.config.memory_info.default_memory + self.mem_hotplug_size_mb;
|
let had_mem_mb = self.config.memory_info.default_memory + self.mem_hotplug_size_mb;
|
||||||
match req_mem_mb.cmp(&had_mem_mb) {
|
match new_mem_mb.cmp(&had_mem_mb) {
|
||||||
Ordering::Greater => {
|
Ordering::Greater => {
|
||||||
// clean virtio-ballon device before hotplug memory, resize to 0
|
// clean virtio-ballon device before hotplug memory, resize to 0
|
||||||
|
if self.balloon_size > 0 {
|
||||||
let balloon_config = BalloonDeviceConfigInfo {
|
let balloon_config = BalloonDeviceConfigInfo {
|
||||||
balloon_id: "balloon0".to_owned(),
|
balloon_id: BALLOON_DEVICE_ID.to_owned(),
|
||||||
size_mib: 0,
|
size_mib: 0,
|
||||||
use_shared_irq: None,
|
use_shared_irq: None,
|
||||||
use_generic_irq: None,
|
use_generic_irq: None,
|
||||||
@ -365,17 +388,18 @@ impl DragonballInner {
|
|||||||
self.vmm_instance
|
self.vmm_instance
|
||||||
.insert_balloon_device(balloon_config)
|
.insert_balloon_device(balloon_config)
|
||||||
.context("failed to insert balloon device")?;
|
.context("failed to insert balloon device")?;
|
||||||
|
}
|
||||||
|
|
||||||
// update the hotplug size
|
// update the hotplug size
|
||||||
self.mem_hotplug_size_mb = req_mem_mb - self.config.memory_info.default_memory;
|
self.mem_hotplug_size_mb = new_mem_mb - self.config.memory_info.default_memory;
|
||||||
|
self.balloon_size = 0;
|
||||||
|
|
||||||
// insert a new memory device
|
let add_mem_mb = new_mem_mb - had_mem_mb;
|
||||||
let add_mem_mb = req_mem_mb - had_mem_mb;
|
|
||||||
self.vmm_instance.insert_mem_device(MemDeviceConfigInfo {
|
self.vmm_instance.insert_mem_device(MemDeviceConfigInfo {
|
||||||
mem_id: format!("mem{}", self.mem_hotplug_size_mb),
|
mem_id: MEM_DEVICE_ID.to_owned(),
|
||||||
size_mib: add_mem_mb as u64,
|
size_mib: add_mem_mb as u64,
|
||||||
capacity_mib: add_mem_mb as u64,
|
capacity_mib: self.hypervisor_config().memory_info.default_maxmemory as u64,
|
||||||
multi_region: false,
|
multi_region: true,
|
||||||
host_numa_node_id: None,
|
host_numa_node_id: None,
|
||||||
guest_numa_node_id: None,
|
guest_numa_node_id: None,
|
||||||
use_shared_irq: None,
|
use_shared_irq: None,
|
||||||
@ -384,15 +408,16 @@ impl DragonballInner {
|
|||||||
}
|
}
|
||||||
Ordering::Less => {
|
Ordering::Less => {
|
||||||
// we only use one balloon device here, and resize it to release memory
|
// we only use one balloon device here, and resize it to release memory
|
||||||
// the operation we do here is inserting a new balloon0 device or resizing it
|
// the operation we do here is inserting a new BALLOON_DEVICE_ID device or resizing it
|
||||||
let balloon_config = BalloonDeviceConfigInfo {
|
let balloon_config = BalloonDeviceConfigInfo {
|
||||||
balloon_id: "balloon0".to_owned(),
|
balloon_id: BALLOON_DEVICE_ID.to_owned(),
|
||||||
size_mib: (had_mem_mb - req_mem_mb) as u64,
|
size_mib: (had_mem_mb - new_mem_mb) as u64,
|
||||||
use_shared_irq: None,
|
use_shared_irq: None,
|
||||||
use_generic_irq: None,
|
use_generic_irq: None,
|
||||||
f_deflate_on_oom: false,
|
f_deflate_on_oom: false,
|
||||||
f_reporting: false,
|
f_reporting: false,
|
||||||
};
|
};
|
||||||
|
self.balloon_size = had_mem_mb - new_mem_mb;
|
||||||
self.vmm_instance
|
self.vmm_instance
|
||||||
.insert_balloon_device(balloon_config)
|
.insert_balloon_device(balloon_config)
|
||||||
.context("failed to insert balloon device")?;
|
.context("failed to insert balloon device")?;
|
||||||
@ -407,7 +432,7 @@ impl DragonballInner {
|
|||||||
};
|
};
|
||||||
|
|
||||||
Ok((
|
Ok((
|
||||||
req_mem_mb,
|
new_mem_mb,
|
||||||
MemoryConfig {
|
MemoryConfig {
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
@ -476,6 +501,7 @@ impl Persist for DragonballInner {
|
|||||||
capabilities: Capabilities::new(),
|
capabilities: Capabilities::new(),
|
||||||
guest_memory_block_size_mb: 0,
|
guest_memory_block_size_mb: 0,
|
||||||
mem_hotplug_size_mb: 0,
|
mem_hotplug_size_mb: 0,
|
||||||
|
balloon_size: 0,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -194,9 +194,9 @@ impl Hypervisor for Dragonball {
|
|||||||
inner.guest_memory_block_size_mb()
|
inner.guest_memory_block_size_mb()
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn resize_memory(&self, req_mem_mb: u32) -> Result<(u32, MemoryConfig)> {
|
async fn resize_memory(&self, new_mem_mb: u32) -> Result<(u32, MemoryConfig)> {
|
||||||
let mut inner = self.inner.write().await;
|
let mut inner = self.inner.write().await;
|
||||||
inner.resize_memory(req_mem_mb)
|
inner.resize_memory(new_mem_mb)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,7 +91,7 @@ pub trait Hypervisor: std::fmt::Debug + Send + Sync {
|
|||||||
async fn save_vm(&self) -> Result<()>;
|
async fn save_vm(&self) -> Result<()>;
|
||||||
async fn resume_vm(&self) -> Result<()>;
|
async fn resume_vm(&self) -> Result<()>;
|
||||||
async fn resize_vcpu(&self, old_vcpus: u32, new_vcpus: u32) -> Result<(u32, u32)>; // returns (old_vcpus, new_vcpus)
|
async fn resize_vcpu(&self, old_vcpus: u32, new_vcpus: u32) -> Result<(u32, u32)>; // returns (old_vcpus, new_vcpus)
|
||||||
async fn resize_memory(&self, req_mem_mb: u32) -> Result<(u32, MemoryConfig)>;
|
async fn resize_memory(&self, new_mem_mb: u32) -> Result<(u32, MemoryConfig)>;
|
||||||
|
|
||||||
// device manager
|
// device manager
|
||||||
async fn add_device(&self, device: DeviceType) -> Result<DeviceType>;
|
async fn add_device(&self, device: DeviceType) -> Result<DeviceType>;
|
||||||
|
@ -153,7 +153,7 @@ impl QemuInner {
|
|||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn resize_memory(&self, _req_mem_mb: u32) -> Result<(u32, MemoryConfig)> {
|
pub(crate) fn resize_memory(&self, _new_mem_mb: u32) -> Result<(u32, MemoryConfig)> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -173,8 +173,8 @@ impl Hypervisor for Qemu {
|
|||||||
inner.guest_memory_block_size_mb()
|
inner.guest_memory_block_size_mb()
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn resize_memory(&self, req_mem_mb: u32) -> Result<(u32, MemoryConfig)> {
|
async fn resize_memory(&self, new_mem_mb: u32) -> Result<(u32, MemoryConfig)> {
|
||||||
let inner = self.inner.read().await;
|
let inner = self.inner.read().await;
|
||||||
inner.resize_memory(req_mem_mb)
|
inner.resize_memory(new_mem_mb)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,6 @@ use std::sync::Arc;
|
|||||||
|
|
||||||
use anyhow::{Context, Ok, Result};
|
use anyhow::{Context, Ok, Result};
|
||||||
use hypervisor::Hypervisor;
|
use hypervisor::Hypervisor;
|
||||||
use kata_types::config::TomlConfig;
|
|
||||||
use oci::LinuxResources;
|
use oci::LinuxResources;
|
||||||
use tokio::sync::RwLock;
|
use tokio::sync::RwLock;
|
||||||
|
|
||||||
@ -21,31 +20,17 @@ pub const MIB_TO_BYTES_SHIFT: i32 = 20;
|
|||||||
|
|
||||||
#[derive(Default, Debug, Clone)]
|
#[derive(Default, Debug, Clone)]
|
||||||
pub struct MemResource {
|
pub struct MemResource {
|
||||||
/// Current memory
|
|
||||||
pub(crate) current_mem: Arc<RwLock<u32>>,
|
|
||||||
|
|
||||||
/// Default memory
|
/// Default memory
|
||||||
pub(crate) orig_toml_default_mem: u32,
|
pub(crate) orig_toml_default_mem: u32,
|
||||||
|
|
||||||
/// MemResource of each container
|
/// MemResource of each container
|
||||||
pub(crate) container_mem_resources: Arc<RwLock<HashMap<String, LinuxResources>>>,
|
pub(crate) container_mem_resources: Arc<RwLock<HashMap<String, LinuxResources>>>,
|
||||||
|
|
||||||
/// Use guest swap
|
|
||||||
pub(crate) use_guest_swap: bool,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MemResource {
|
impl MemResource {
|
||||||
pub fn new(config: Arc<TomlConfig>, init_size_manager: InitialSizeManager) -> Result<Self> {
|
pub fn new(init_size_manager: InitialSizeManager) -> Result<Self> {
|
||||||
let hypervisor_name = config.runtime.hypervisor_name.clone();
|
|
||||||
let hypervisor_config = config
|
|
||||||
.hypervisor
|
|
||||||
.get(&hypervisor_name)
|
|
||||||
.context("failed to get hypervisor")?;
|
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
current_mem: Arc::new(RwLock::new(hypervisor_config.memory_info.default_memory)),
|
|
||||||
container_mem_resources: Arc::new(RwLock::new(HashMap::new())),
|
container_mem_resources: Arc::new(RwLock::new(HashMap::new())),
|
||||||
use_guest_swap: hypervisor_config.memory_info.enable_guest_swap,
|
|
||||||
orig_toml_default_mem: init_size_manager.get_orig_toml_default_mem(),
|
orig_toml_default_mem: init_size_manager.get_orig_toml_default_mem(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -61,36 +46,23 @@ impl MemResource {
|
|||||||
.await
|
.await
|
||||||
.context("update container memory resources")?;
|
.context("update container memory resources")?;
|
||||||
// the unit here is MB
|
// the unit here is MB
|
||||||
let (mut mem_sb_mb, need_pod_swap, swap_sb_mb) = self
|
let mut mem_sb_mb = self
|
||||||
.total_mems(self.use_guest_swap)
|
.total_mems()
|
||||||
.await
|
.await
|
||||||
.context("failed to calculate total memory requirement for containers")?;
|
.context("failed to calculate total memory requirement for containers")?;
|
||||||
mem_sb_mb += self.orig_toml_default_mem;
|
mem_sb_mb += self.orig_toml_default_mem;
|
||||||
if need_pod_swap {
|
|
||||||
mem_sb_mb += swap_sb_mb;
|
|
||||||
}
|
|
||||||
info!(sl!(), "calculate mem_sb_mb {}", mem_sb_mb);
|
info!(sl!(), "calculate mem_sb_mb {}", mem_sb_mb);
|
||||||
|
|
||||||
let curr_mem = self
|
let _curr_mem = self
|
||||||
.do_update_mem_resource(mem_sb_mb, swap_sb_mb, hypervisor)
|
.do_update_mem_resource(mem_sb_mb, hypervisor)
|
||||||
.await
|
.await
|
||||||
.context("failed to update_mem_resource")?;
|
.context("failed to update_mem_resource")?;
|
||||||
|
|
||||||
self.update_current_mem(curr_mem).await;
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn update_current_mem(&self, new_mem: u32) {
|
async fn total_mems(&self) -> Result<u32> {
|
||||||
let mut current_mem = self.current_mem.write().await;
|
|
||||||
*current_mem = new_mem;
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn total_mems(&self, use_guest_swap: bool) -> Result<(u32, bool, u32)> {
|
|
||||||
// sb stands for sandbox
|
|
||||||
let mut mem_sandbox = 0;
|
let mut mem_sandbox = 0;
|
||||||
let mut need_pod_swap = false;
|
|
||||||
let mut swap_sandbox = 0;
|
|
||||||
|
|
||||||
let resources = self.container_mem_resources.read().await;
|
let resources = self.container_mem_resources.read().await;
|
||||||
|
|
||||||
for (_, r) in resources.iter() {
|
for (_, r) in resources.iter() {
|
||||||
@ -100,36 +72,17 @@ impl MemResource {
|
|||||||
|
|
||||||
if let Some(memory) = &r.memory {
|
if let Some(memory) = &r.memory {
|
||||||
// set current_limit to 0 if memory limit is not set to container
|
// set current_limit to 0 if memory limit is not set to container
|
||||||
let current_limit = memory.limit.map_or(0, |limit| {
|
let _current_limit = memory.limit.map_or(0, |limit| {
|
||||||
mem_sandbox += limit as u64;
|
mem_sandbox += limit as u64;
|
||||||
info!(sl!(), "memory sb: {}, memory limit: {}", mem_sandbox, limit);
|
info!(sl!(), "memory sb: {}, memory limit: {}", mem_sandbox, limit);
|
||||||
limit
|
limit
|
||||||
});
|
});
|
||||||
|
// TODO support memory guest swap
|
||||||
if let Some(swappiness) = memory.swappiness {
|
// https://github.com/kata-containers/kata-containers/issues/7293
|
||||||
if swappiness > 0 && use_guest_swap {
|
|
||||||
if let Some(swap) = memory.swap {
|
|
||||||
if swap > current_limit {
|
|
||||||
swap_sandbox = swap.saturating_sub(current_limit);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// if current_limit is 0, the container will have access to the entire memory available on the host system
|
|
||||||
// so we add swap for this
|
|
||||||
else if current_limit == 0 {
|
|
||||||
need_pod_swap = true;
|
|
||||||
} else {
|
|
||||||
swap_sandbox += current_limit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok((
|
Ok((mem_sandbox >> MIB_TO_BYTES_SHIFT) as u32)
|
||||||
(mem_sandbox >> MIB_TO_BYTES_SHIFT) as u32,
|
|
||||||
need_pod_swap,
|
|
||||||
(swap_sandbox >> MIB_TO_BYTES_SHIFT) as u32,
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// update container_cpu_resources field
|
// update container_cpu_resources field
|
||||||
@ -156,10 +109,10 @@ impl MemResource {
|
|||||||
async fn do_update_mem_resource(
|
async fn do_update_mem_resource(
|
||||||
&self,
|
&self,
|
||||||
new_mem: u32,
|
new_mem: u32,
|
||||||
_swap_sz_mb: u32,
|
|
||||||
hypervisor: &dyn Hypervisor,
|
hypervisor: &dyn Hypervisor,
|
||||||
) -> Result<u32> {
|
) -> Result<u32> {
|
||||||
info!(sl!(), "requesting vmm to update memory to {:?}", new_mem);
|
info!(sl!(), "requesting vmm to update memory to {:?}", new_mem);
|
||||||
|
|
||||||
let (new_memory, _mem_config) = hypervisor
|
let (new_memory, _mem_config) = hypervisor
|
||||||
.resize_memory(new_mem)
|
.resize_memory(new_mem)
|
||||||
.await
|
.await
|
||||||
|
@ -66,7 +66,7 @@ impl ResourceManagerInner {
|
|||||||
|
|
||||||
let cgroups_resource = CgroupsResource::new(sid, &toml_config)?;
|
let cgroups_resource = CgroupsResource::new(sid, &toml_config)?;
|
||||||
let cpu_resource = CpuResource::new(toml_config.clone())?;
|
let cpu_resource = CpuResource::new(toml_config.clone())?;
|
||||||
let mem_resource = MemResource::new(toml_config.clone(), init_size_manager)?;
|
let mem_resource = MemResource::new(init_size_manager)?;
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
sid: sid.to_string(),
|
sid: sid.to_string(),
|
||||||
toml_config,
|
toml_config,
|
||||||
|
@ -222,7 +222,7 @@ impl VirtSandbox {
|
|||||||
// set memory hotplug probe
|
// set memory hotplug probe
|
||||||
if guest_details.support_mem_hotplug_probe {
|
if guest_details.support_mem_hotplug_probe {
|
||||||
self.hypervisor
|
self.hypervisor
|
||||||
.set_capabilities(CapabilityBits::GuestMemoryHotplugProbe)
|
.set_capabilities(CapabilityBits::GuestMemoryProbe)
|
||||||
.await;
|
.await;
|
||||||
}
|
}
|
||||||
info!(
|
info!(
|
||||||
|
Loading…
Reference in New Issue
Block a user