crosvm: Make ballooning a compile time feature

Balloon support can not be compiled out, and don't need to be
disabled at run time.

BUG=b:235887451
TEST=Guest has balloon device by default, does not have balloon
device when disabled. Ballooning via cli functions by default,
return not supported when running vm has ballooning compiled out.

Change-Id: I737851496fe4c14cdbb69c48e6edf1ca9186c15a
Reviewed-on: https://chromium-review.googlesource.com/c/crosvm/crosvm/+/3786928
Tested-by: Zihan Chen <zihanchen@google.com>
Reviewed-by: Daniel Verkamp <dverkamp@chromium.org>
Commit-Queue: Zihan Chen <zihanchen@google.com>
This commit is contained in:
Zihan Chen 2022-07-25 16:54:13 -07:00 committed by crosvm LUCI
parent 1884bfd37f
commit 11812a5bf9
10 changed files with 62 additions and 18 deletions

View file

@ -122,12 +122,13 @@ all-linux = [
win64 = []
audio = ["devices/audio"]
audio_cras = ["devices/audio_cras"]
balloon = ["devices/balloon", "vm_control/balloon"]
chromeos = ["base/chromeos", "audio_cras", "devices/chromeos"]
composite-disk = ["protos/composite-disk", "protobuf", "disk/composite-disk"]
crash-report = []
default = ["audio", "gpu", "usb"]
default = ["audio", "balloon", "gpu", "usb"]
default-no-sandbox = []
direct = ["devices/direct", "arch/direct", "x86_64/direct"]
direct = ["balloon", "devices/direct", "arch/direct", "x86_64/direct"]
ffmpeg = ["devices/ffmpeg"]
gdb = ["gdbstub", "gdbstub_arch", "arch/gdb", "vm_control/gdb", "x86_64/gdb"]
gfxstream = ["devices/gfxstream"]

View file

@ -7,6 +7,7 @@ edition = "2021"
[features]
audio = []
audio_cras = ["libcras"]
balloon = []
chromeos = ["dbus", "protobuf", "system_api"]
direct = []
gpu = ["gpu_display","rutabaga_gfx"]

View file

@ -974,7 +974,7 @@ impl CoIommuDev {
mem: GuestMemory,
vfio_container: Arc<Mutex<VfioContainer>>,
device_tube: Tube,
unpin_tube: Tube,
unpin_tube: Option<Tube>,
endpoints: Vec<u16>,
vcpu_count: u64,
params: CoIommuParameters,
@ -1043,7 +1043,7 @@ impl CoIommuDev {
pin_kill_evt: None,
unpin_thread: None,
unpin_kill_evt: None,
unpin_tube: Some(unpin_tube),
unpin_tube,
ioevents,
vfio_container,
pinstate: Arc::new(Mutex::new(CoIommuPinState {

View file

@ -6,6 +6,7 @@
mod async_device;
mod async_utils;
#[cfg(feature = "balloon")]
mod balloon;
mod descriptor_utils;
mod input;
@ -28,6 +29,7 @@ pub mod resource_bridge;
pub mod snd;
pub mod vhost;
#[cfg(feature = "balloon")]
pub use self::balloon::*;
pub use self::block::*;
pub use self::console::*;

View file

@ -96,7 +96,9 @@ pub struct CrosvmCmdlineArgs {
#[derive(FromArgs)]
#[argh(subcommand)]
pub enum CrossPlatformCommands {
#[cfg(feature = "balloon")]
Balloon(BalloonCommand),
#[cfg(feature = "balloon")]
BalloonStats(BalloonStatsCommand),
Battery(BatteryCommand),
#[cfg(feature = "composite-disk")]

View file

@ -27,12 +27,14 @@ use std::os::unix::prelude::OpenOptionsExt;
use std::path::Path;
use std::str::FromStr;
use std::sync::{mpsc, Arc, Barrier};
#[cfg(feature = "balloon")]
use std::time::Duration;
use std::process;
#[cfg(all(target_arch = "x86_64", feature = "gdb"))]
use std::thread;
#[cfg(feature = "balloon")]
use devices::virtio::BalloonMode;
use libc;
@ -114,9 +116,9 @@ fn create_virtio_devices(
vm_evt_wrtube: &SendTube,
gpu_device_tube: Tube,
vhost_user_gpu_tubes: Vec<(Tube, Tube, Tube)>,
balloon_device_tube: Option<Tube>,
balloon_inflate_tube: Option<Tube>,
init_balloon_size: u64,
#[cfg(feature = "balloon")] balloon_device_tube: Option<Tube>,
#[cfg(feature = "balloon")] balloon_inflate_tube: Option<Tube>,
#[cfg(feature = "balloon")] init_balloon_size: u64,
disk_device_tubes: &mut Vec<Tube>,
pmem_device_tubes: &mut Vec<Tube>,
map_request: Arc<Mutex<Option<ExternalMapping>>>,
@ -386,6 +388,7 @@ fn create_virtio_devices(
)?);
}
#[cfg(feature = "balloon")]
if let Some(balloon_device_tube) = balloon_device_tube {
devs.push(create_balloon_device(
cfg.protected_vm,
@ -589,8 +592,8 @@ fn create_devices(
gpu_device_tube: Tube,
// Tuple content: (host-side GPU tube, device-side GPU tube, device-side control tube).
vhost_user_gpu_tubes: Vec<(Tube, Tube, Tube)>,
balloon_device_tube: Option<Tube>,
init_balloon_size: u64,
#[cfg(feature = "balloon")] balloon_device_tube: Option<Tube>,
#[cfg(feature = "balloon")] init_balloon_size: u64,
disk_device_tubes: &mut Vec<Tube>,
pmem_device_tubes: &mut Vec<Tube>,
fs_device_tubes: &mut Vec<Tube>,
@ -602,6 +605,7 @@ fn create_devices(
iova_max_addr: &mut Option<u64>,
) -> DeviceResult<Vec<(Box<dyn BusDeviceObj>, Option<Minijail>)>> {
let mut devices: Vec<(Box<dyn BusDeviceObj>, Option<Minijail>)> = Vec::new();
#[cfg(feature = "balloon")]
let mut balloon_inflate_tube: Option<Tube> = None;
if !cfg.vfio.is_empty() {
let mut coiommu_attached_endpoints = Vec::new();
@ -684,7 +688,10 @@ fn create_devices(
bail!("Get rlimit failed");
}
}
#[cfg(feature = "balloon")]
let coiommu_tube: Option<Tube>;
#[cfg(not(feature = "balloon"))]
let coiommu_tube: Option<Tube> = None;
if !coiommu_attached_endpoints.is_empty() {
let vfio_container =
VfioCommonSetup::vfio_get_container(IommuDevType::CoIommu, None as Option<&Path>)
@ -693,9 +700,14 @@ fn create_devices(
Tube::pair().context("failed to create coiommu tube")?;
control_tubes.push(TaggedControlTube::VmMemory(coiommu_host_tube));
let vcpu_count = cfg.vcpu_count.unwrap_or(1) as u64;
let (coiommu_tube, balloon_tube) =
Tube::pair().context("failed to create coiommu tube")?;
balloon_inflate_tube = Some(balloon_tube);
#[cfg(feature = "balloon")]
match Tube::pair() {
Ok((x, y)) => {
coiommu_tube = Some(x);
balloon_inflate_tube = Some(y);
}
Err(x) => return Err(x).context("failed to create coiommu tube"),
}
let dev = CoIommuDev::new(
vm.get_memory().clone(),
vfio_container,
@ -721,8 +733,11 @@ fn create_devices(
vm_evt_wrtube,
gpu_device_tube,
vhost_user_gpu_tubes,
#[cfg(feature = "balloon")]
balloon_device_tube,
#[cfg(feature = "balloon")]
balloon_inflate_tube,
#[cfg(feature = "balloon")]
init_balloon_size,
disk_device_tubes,
pmem_device_tubes,
@ -1311,6 +1326,7 @@ where
control_tubes.push(TaggedControlTube::VmMemory(host_control_tube));
}
#[cfg(feature = "balloon")]
let (balloon_host_tube, balloon_device_tube) = if cfg.balloon {
if let Some(ref path) = cfg.balloon_control {
(
@ -1446,6 +1462,7 @@ where
(None, None)
};
#[cfg(feature = "balloon")]
let init_balloon_size = components
.memory_size
.checked_sub(cfg.init_memory.map_or(components.memory_size, |m| {
@ -1531,7 +1548,9 @@ where
&mut control_tubes,
gpu_device_tube,
vhost_user_gpu_tubes,
#[cfg(feature = "balloon")]
balloon_device_tube,
#[cfg(feature = "balloon")]
init_balloon_size,
&mut disk_device_tubes,
&mut pmem_device_tubes,
@ -1698,6 +1717,7 @@ where
cfg,
control_server_socket,
control_tubes,
#[cfg(feature = "balloon")]
balloon_host_tube,
&disk_host_tubes,
#[cfg(feature = "usb")]
@ -1877,7 +1897,7 @@ fn run_control<V: VmArch + 'static, Vcpu: VcpuArch + 'static>(
cfg: Config,
control_server_socket: Option<UnlinkUnixSeqpacketListener>,
mut control_tubes: Vec<TaggedControlTube>,
balloon_host_tube: Option<Tube>,
#[cfg(feature = "balloon")] balloon_host_tube: Option<Tube>,
disk_host_tubes: &[Tube],
#[cfg(feature = "usb")] usb_control_tube: Tube,
vm_evt_rdtube: RecvTube,
@ -2067,6 +2087,7 @@ fn run_control<V: VmArch + 'static, Vcpu: VcpuArch + 'static>(
let mut exit_state = ExitState::Stop;
let mut pvpanic_code = PvPanicCode::Unknown;
#[cfg(feature = "balloon")]
let mut balloon_stats_id: u64 = 0;
'wait: loop {
@ -2194,7 +2215,9 @@ fn run_control<V: VmArch + 'static, Vcpu: VcpuArch + 'static>(
),
_ => request.execute(
&mut run_mode_opt,
#[cfg(feature = "balloon")]
balloon_host_tube.as_ref(),
#[cfg(feature = "balloon")]
&mut balloon_stats_id,
disk_host_tubes,
&mut linux.pm,

View file

@ -37,9 +37,11 @@ use devices::virtio::vhost::user::vmm::{
Wl as VhostUserWl,
};
use devices::virtio::vhost::vsock::VhostVsockConfig;
#[cfg(feature = "balloon")]
use devices::virtio::BalloonMode;
#[cfg(any(feature = "video-decoder", feature = "video-encoder"))]
use devices::virtio::VideoBackendType;
use devices::virtio::{self, BalloonMode, VirtioDevice};
use devices::virtio::{self, VirtioDevice};
use devices::IommuDevType;
#[cfg(feature = "tpm")]
use devices::SoftwareTpm;
@ -639,6 +641,7 @@ pub fn create_vinput_device(
})
}
#[cfg(feature = "balloon")]
pub fn create_balloon_device(
protected_vm: ProtectionType,
jail_config: &Option<JailConfig>,

View file

@ -29,8 +29,10 @@ use vm_control::{
do_modify_battery, do_usb_attach, do_usb_detach, do_usb_list, handle_request, vms_request,
ModifyUsbResult,
},
BalloonControlCommand, DiskControlCommand, UsbControlResult, VmRequest, VmResponse,
DiskControlCommand, UsbControlResult, VmRequest,
};
#[cfg(feature = "balloon")]
use vm_control::{BalloonControlCommand, VmResponse};
use crate::sys::error_to_exit_code;
use crate::sys::init_log;
@ -137,6 +139,7 @@ fn inject_gpe(cmd: cmdline::GpeCommand) -> std::result::Result<(), ()> {
vms_request(&VmRequest::Gpe(cmd.gpe), cmd.socket_path)
}
#[cfg(feature = "balloon")]
fn balloon_vms(cmd: cmdline::BalloonCommand) -> std::result::Result<(), ()> {
let command = BalloonControlCommand::Adjust {
num_bytes: cmd.num_bytes,
@ -144,6 +147,7 @@ fn balloon_vms(cmd: cmdline::BalloonCommand) -> std::result::Result<(), ()> {
vms_request(&VmRequest::BalloonCommand(command), cmd.socket_path)
}
#[cfg(feature = "balloon")]
fn balloon_stats(cmd: cmdline::BalloonStatsCommand) -> std::result::Result<(), ()> {
let command = BalloonControlCommand::Stats {};
let request = &VmRequest::BalloonCommand(command);
@ -527,9 +531,11 @@ fn crosvm_main() -> Result<CommandStatus> {
.map_err(|e| anyhow!("failed to initialize syslog: {}", e))?;
match command {
#[cfg(feature = "balloon")]
CrossPlatformCommands::Balloon(cmd) => {
balloon_vms(cmd).map_err(|_| anyhow!("balloon subcommand failed"))
}
#[cfg(feature = "balloon")]
CrossPlatformCommands::BalloonStats(cmd) => {
balloon_stats(cmd).map_err(|_| anyhow!("balloon_stats subcommand failed"))
}

View file

@ -5,6 +5,7 @@ authors = ["The Chromium OS Authors"]
edition = "2021"
[features]
balloon = []
gdb = ["gdbstub_arch"]
[dependencies]

View file

@ -39,6 +39,7 @@ use libc::{EINVAL, EIO, ENODEV, ENOTSUP, ERANGE};
use serde::{Deserialize, Serialize};
pub use balloon_control::BalloonStats;
#[cfg(feature = "balloon")]
use balloon_control::{BalloonTubeCommand, BalloonTubeResult};
use base::{
@ -844,8 +845,8 @@ impl VmRequest {
pub fn execute(
&self,
run_mode: &mut Option<VmRunMode>,
balloon_host_tube: Option<&Tube>,
balloon_stats_id: &mut u64,
#[cfg(feature = "balloon")] balloon_host_tube: Option<&Tube>,
#[cfg(feature = "balloon")] balloon_stats_id: &mut u64,
disk_host_tubes: &[Tube],
pm: &mut Option<Arc<Mutex<dyn PmResource>>>,
usb_control_tube: Option<&Tube>,
@ -920,6 +921,7 @@ impl VmRequest {
}
VmResponse::Ok
}
#[cfg(feature = "balloon")]
VmRequest::BalloonCommand(BalloonControlCommand::Adjust { num_bytes }) => {
if let Some(balloon_host_tube) = balloon_host_tube {
match balloon_host_tube.send(&BalloonTubeCommand::Adjust {
@ -933,6 +935,7 @@ impl VmRequest {
VmResponse::Err(SysError::new(ENOTSUP))
}
}
#[cfg(feature = "balloon")]
VmRequest::BalloonCommand(BalloonControlCommand::Stats) => {
if let Some(balloon_host_tube) = balloon_host_tube {
// NB: There are a few reasons stale balloon stats could be left
@ -982,6 +985,8 @@ impl VmRequest {
VmResponse::Err(SysError::new(ENOTSUP))
}
}
#[cfg(not(feature = "balloon"))]
VmRequest::BalloonCommand(_) => VmResponse::Err(SysError::new(ENOTSUP)),
VmRequest::DiskCommand {
disk_index,
ref command,