Refactor VM config to support different CPU topologies
This is preliminary work to support crosvm's --host-cpu-topology (WIP),
which will make it possible to mirror host's CPU topology in the guest.
As a first step, we refactor AVF's system API to stop accepting number
of vCPUs as an argument, but instead only expose two topology configs:
1 vCPU (default) and matching the host's CPU topology.
For the time being, the latter results in crosvm started with `--cpu
<nproc>`.
Bug: 266664564
Test: atest -p packages/modules/Virtualization:avf-presubmit
Change-Id: I03a37be0b68b93dc0fa6e84fd51ca3bdefbe6dde
diff --git a/virtualizationmanager/src/atom.rs b/virtualizationmanager/src/atom.rs
index c33f262..567fce9 100644
--- a/virtualizationmanager/src/atom.rs
+++ b/virtualizationmanager/src/atom.rs
@@ -19,6 +19,7 @@
use crate::get_calling_uid;
use android_system_virtualizationcommon::aidl::android::system::virtualizationcommon::DeathReason::DeathReason;
use android_system_virtualizationservice::aidl::android::system::virtualizationservice::{
+ CpuTopology::CpuTopology,
IVirtualMachine::IVirtualMachine,
VirtualMachineAppConfig::{Payload::Payload, VirtualMachineAppConfig},
VirtualMachineConfig::VirtualMachineConfig,
@@ -38,6 +39,8 @@
use std::time::{Duration, SystemTime};
use zip::ZipArchive;
+const INVALID_NUM_CPUS: i32 = -1;
+
fn get_apex_list(config: &VirtualMachineAppConfig) -> String {
match &config.payload {
Payload::PayloadConfig(_) => String::new(),
@@ -76,6 +79,19 @@
}
}
+// Returns the number of CPUs configured in the host system.
+// This matches how crosvm determines the number of logical cores.
+// For telemetry purposes only.
+pub(crate) fn get_num_cpus() -> Option<usize> {
+ // SAFETY - Only integer constants passed back and forth.
+ let ret = unsafe { libc::sysconf(libc::_SC_NPROCESSORS_CONF) };
+ if ret > 0 {
+ ret.try_into().ok()
+ } else {
+ None
+ }
+}
+
/// Write the stats of VMCreation to statsd
pub fn write_vm_creation_stats(
config: &VirtualMachineConfig,
@@ -94,23 +110,33 @@
binder_exception_code = e.exception_code() as i32;
}
}
- let (vm_identifier, config_type, num_cpus, memory_mib, apexes) = match config {
+ let (vm_identifier, config_type, cpu_topology, memory_mib, apexes) = match config {
VirtualMachineConfig::AppConfig(config) => (
config.name.clone(),
vm_creation_requested::ConfigType::VirtualMachineAppConfig,
- config.numCpus,
+ config.cpuTopology,
config.memoryMib,
get_apex_list(config),
),
VirtualMachineConfig::RawConfig(config) => (
config.name.clone(),
vm_creation_requested::ConfigType::VirtualMachineRawConfig,
- config.numCpus,
+ config.cpuTopology,
config.memoryMib,
String::new(),
),
};
+ let num_cpus: i32 = match cpu_topology {
+ CpuTopology::MATCH_HOST => {
+ get_num_cpus().and_then(|v| v.try_into().ok()).unwrap_or_else(|| {
+ warn!("Failed to determine the number of CPUs in the host");
+ INVALID_NUM_CPUS
+ })
+ }
+ _ => 1,
+ };
+
let atom = AtomVmCreationRequested {
uid: get_calling_uid() as i32,
vmIdentifier: vm_identifier,