mirror of
https://chromium.googlesource.com/crosvm/crosvm
synced 2025-02-05 18:20:34 +00:00
crosvm: Add support to pass vcpu-cgroup-path to crosvm
The latency reduces to 50-100ms max from over 1 second, when we overload the system. BUG=b:208138181 TEST=run stress-ng inside and outside VM. Change-Id: I10a22807b47a1ed2dd181c2ddcc995eebef7f652 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/3383936 Reviewed-by: Daniel Verkamp <dverkamp@chromium.org> Tested-by: kokoro <noreply+kokoro@google.com> Commit-Queue: Vineeth Pillai <vineethrp@google.com>
This commit is contained in:
parent
33f982e179
commit
2b6855e725
3 changed files with 41 additions and 1 deletions
|
@ -332,6 +332,7 @@ pub struct Config {
|
||||||
pub vhost_vsock_device: Option<VhostVsockDeviceParameter>,
|
pub vhost_vsock_device: Option<VhostVsockDeviceParameter>,
|
||||||
pub vhost_net_device_path: PathBuf,
|
pub vhost_net_device_path: PathBuf,
|
||||||
pub vcpu_count: Option<usize>,
|
pub vcpu_count: Option<usize>,
|
||||||
|
pub vcpu_cgroup_path: Option<PathBuf>,
|
||||||
pub rt_cpus: Vec<usize>,
|
pub rt_cpus: Vec<usize>,
|
||||||
pub vcpu_affinity: Option<VcpuAffinity>,
|
pub vcpu_affinity: Option<VcpuAffinity>,
|
||||||
pub cpu_clusters: Vec<Vec<usize>>,
|
pub cpu_clusters: Vec<Vec<usize>>,
|
||||||
|
@ -436,6 +437,7 @@ impl Default for Config {
|
||||||
vhost_vsock_device: None,
|
vhost_vsock_device: None,
|
||||||
vhost_net_device_path: PathBuf::from(VHOST_NET_PATH),
|
vhost_net_device_path: PathBuf::from(VHOST_NET_PATH),
|
||||||
vcpu_count: None,
|
vcpu_count: None,
|
||||||
|
vcpu_cgroup_path: None,
|
||||||
rt_cpus: Vec::new(),
|
rt_cpus: Vec::new(),
|
||||||
vcpu_affinity: None,
|
vcpu_affinity: None,
|
||||||
cpu_clusters: Vec::new(),
|
cpu_clusters: Vec::new(),
|
||||||
|
|
28
src/linux.rs
28
src/linux.rs
|
@ -8,6 +8,7 @@ use std::convert::{TryFrom, TryInto};
|
||||||
#[cfg(feature = "gpu")]
|
#[cfg(feature = "gpu")]
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::fs::{File, OpenOptions};
|
use std::fs::{File, OpenOptions};
|
||||||
|
use std::io::prelude::*;
|
||||||
use std::io::stdin;
|
use std::io::stdin;
|
||||||
use std::iter;
|
use std::iter;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
@ -19,6 +20,7 @@ use std::str;
|
||||||
use std::sync::{mpsc, Arc, Barrier};
|
use std::sync::{mpsc, Arc, Barrier};
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
|
use std::process;
|
||||||
use std::thread;
|
use std::thread;
|
||||||
use std::thread::JoinHandle;
|
use std::thread::JoinHandle;
|
||||||
|
|
||||||
|
@ -404,7 +406,6 @@ fn create_cras_snd_device(cfg: &Config, cras_snd: CrasSndParameters) -> DeviceRe
|
||||||
fn create_tpm_device(cfg: &Config) -> DeviceResult {
|
fn create_tpm_device(cfg: &Config) -> DeviceResult {
|
||||||
use std::ffi::CString;
|
use std::ffi::CString;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::process;
|
|
||||||
|
|
||||||
let tpm_storage: PathBuf;
|
let tpm_storage: PathBuf;
|
||||||
let mut tpm_jail = simple_jail(cfg, "tpm_device")?;
|
let mut tpm_jail = simple_jail(cfg, "tpm_device")?;
|
||||||
|
@ -2300,6 +2301,7 @@ fn runnable_vcpu<V>(
|
||||||
use_hypervisor_signals: bool,
|
use_hypervisor_signals: bool,
|
||||||
enable_per_vm_core_scheduling: bool,
|
enable_per_vm_core_scheduling: bool,
|
||||||
host_cpu_topology: bool,
|
host_cpu_topology: bool,
|
||||||
|
vcpu_cgroup_tasks_file: Option<File>,
|
||||||
) -> Result<(V, VcpuRunHandle)>
|
) -> Result<(V, VcpuRunHandle)>
|
||||||
where
|
where
|
||||||
V: VcpuArch,
|
V: VcpuArch,
|
||||||
|
@ -2350,6 +2352,12 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Move vcpu thread to cgroup
|
||||||
|
if let Some(mut f) = vcpu_cgroup_tasks_file {
|
||||||
|
f.write_all(base::gettid().to_string().as_bytes())
|
||||||
|
.context("failed to write vcpu tid to cgroup tasks")?;
|
||||||
|
}
|
||||||
|
|
||||||
if run_rt {
|
if run_rt {
|
||||||
const DEFAULT_VCPU_RT_LEVEL: u16 = 6;
|
const DEFAULT_VCPU_RT_LEVEL: u16 = 6;
|
||||||
if let Err(e) = set_rt_prio_limit(u64::from(DEFAULT_VCPU_RT_LEVEL))
|
if let Err(e) = set_rt_prio_limit(u64::from(DEFAULT_VCPU_RT_LEVEL))
|
||||||
|
@ -2476,6 +2484,7 @@ fn run_vcpu<V>(
|
||||||
>,
|
>,
|
||||||
enable_per_vm_core_scheduling: bool,
|
enable_per_vm_core_scheduling: bool,
|
||||||
host_cpu_topology: bool,
|
host_cpu_topology: bool,
|
||||||
|
vcpu_cgroup_tasks_file: Option<File>,
|
||||||
) -> Result<JoinHandle<()>>
|
) -> Result<JoinHandle<()>>
|
||||||
where
|
where
|
||||||
V: VcpuArch + 'static,
|
V: VcpuArch + 'static,
|
||||||
|
@ -2503,6 +2512,7 @@ where
|
||||||
use_hypervisor_signals,
|
use_hypervisor_signals,
|
||||||
enable_per_vm_core_scheduling,
|
enable_per_vm_core_scheduling,
|
||||||
host_cpu_topology,
|
host_cpu_topology,
|
||||||
|
vcpu_cgroup_tasks_file,
|
||||||
);
|
);
|
||||||
|
|
||||||
start_barrier.wait();
|
start_barrier.wait();
|
||||||
|
@ -3469,6 +3479,15 @@ fn run_control<V: VmArch + 'static, Vcpu: VcpuArch + 'static>(
|
||||||
error!("Failed to enable core scheduling: {}", e);
|
error!("Failed to enable core scheduling: {}", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
let vcpu_cgroup_tasks_file = match &cfg.vcpu_cgroup_path {
|
||||||
|
None => None,
|
||||||
|
Some(cgroup_path) => {
|
||||||
|
// Move main process to cgroup_path
|
||||||
|
let mut f = File::create(&cgroup_path.join("tasks"))?;
|
||||||
|
f.write_all(process::id().to_string().as_bytes())?;
|
||||||
|
Some(f)
|
||||||
|
}
|
||||||
|
};
|
||||||
for (cpu_id, vcpu) in vcpus.into_iter().enumerate() {
|
for (cpu_id, vcpu) in vcpus.into_iter().enumerate() {
|
||||||
let (to_vcpu_channel, from_main_channel) = mpsc::channel();
|
let (to_vcpu_channel, from_main_channel) = mpsc::channel();
|
||||||
let vcpu_affinity = match linux.vcpu_affinity.clone() {
|
let vcpu_affinity = match linux.vcpu_affinity.clone() {
|
||||||
|
@ -3502,6 +3521,13 @@ fn run_control<V: VmArch + 'static, Vcpu: VcpuArch + 'static>(
|
||||||
to_gdb_channel.clone(),
|
to_gdb_channel.clone(),
|
||||||
cfg.per_vm_core_scheduling,
|
cfg.per_vm_core_scheduling,
|
||||||
cfg.host_cpu_topology,
|
cfg.host_cpu_topology,
|
||||||
|
match vcpu_cgroup_tasks_file {
|
||||||
|
None => None,
|
||||||
|
Some(ref f) => Some(
|
||||||
|
f.try_clone()
|
||||||
|
.context("failed to clone vcpu cgroup tasks file")?,
|
||||||
|
),
|
||||||
|
},
|
||||||
)?;
|
)?;
|
||||||
vcpu_handles.push((handle, to_vcpu_channel));
|
vcpu_handles.push((handle, to_vcpu_channel));
|
||||||
}
|
}
|
||||||
|
|
12
src/main.rs
12
src/main.rs
|
@ -1210,6 +1210,17 @@ fn set_argument(cfg: &mut Config, name: &str, value: Option<&str>) -> argument::
|
||||||
"per-vm-core-scheduling" => {
|
"per-vm-core-scheduling" => {
|
||||||
cfg.per_vm_core_scheduling = true;
|
cfg.per_vm_core_scheduling = true;
|
||||||
}
|
}
|
||||||
|
"vcpu-cgroup-path" => {
|
||||||
|
let vcpu_cgroup_path = PathBuf::from(value.unwrap());
|
||||||
|
if !vcpu_cgroup_path.exists() {
|
||||||
|
return Err(argument::Error::InvalidValue {
|
||||||
|
value: value.unwrap().to_owned(),
|
||||||
|
expected: String::from("This vcpu_cgroup_path path does not exist"),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
cfg.vcpu_cgroup_path = Some(vcpu_cgroup_path);
|
||||||
|
}
|
||||||
#[cfg(feature = "audio_cras")]
|
#[cfg(feature = "audio_cras")]
|
||||||
"cras-snd" => {
|
"cras-snd" => {
|
||||||
cfg.cras_snds.push(
|
cfg.cras_snds.push(
|
||||||
|
@ -2442,6 +2453,7 @@ fn run_vm(args: std::env::Args) -> std::result::Result<CommandStatus, ()> {
|
||||||
Argument::flag("per-vm-core-scheduling", "Enable per-VM core scheduling intead of the default one (per-vCPU core scheduing) by
|
Argument::flag("per-vm-core-scheduling", "Enable per-VM core scheduling intead of the default one (per-vCPU core scheduing) by
|
||||||
making all vCPU threads share same cookie for core scheduling.
|
making all vCPU threads share same cookie for core scheduling.
|
||||||
This option is no-op on devices that have neither MDS nor L1TF vulnerability."),
|
This option is no-op on devices that have neither MDS nor L1TF vulnerability."),
|
||||||
|
Argument::value("vcpu-cgroup-path", "PATH", "Move all vCPU threads to this CGroup (default: nothing moves)."),
|
||||||
#[cfg(feature = "audio_cras")]
|
#[cfg(feature = "audio_cras")]
|
||||||
Argument::value("cras-snd",
|
Argument::value("cras-snd",
|
||||||
"[capture=true,client=crosvm,socket=unified,num_output_streams=1,num_input_streams=1]",
|
"[capture=true,client=crosvm,socket=unified,num_output_streams=1,num_input_streams=1]",
|
||||||
|
|
Loading…
Reference in a new issue