vmm: Update NUMA nodes based on NumaConfig

Relying on the list of CPUs defined through the NumaConfig, this patch
will update the internal list of CPUs attached to each NUMA node.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
This commit is contained in:
Sebastien Boeuf 2020-08-28 19:18:33 +02:00
parent 42f963d6f2
commit db28db8567
2 changed files with 39 additions and 2 deletions

View File

@ -66,12 +66,21 @@ struct HotPlugState {
#[derive(Clone)] #[derive(Clone)]
pub struct NumaNode { pub struct NumaNode {
memory_regions: Vec<Arc<GuestRegionMmap>>, memory_regions: Vec<Arc<GuestRegionMmap>>,
cpus: Vec<u8>,
} }
impl NumaNode { impl NumaNode {
pub fn memory_regions(&self) -> &Vec<Arc<GuestRegionMmap>> { pub fn memory_regions(&self) -> &Vec<Arc<GuestRegionMmap>> {
&self.memory_regions &self.memory_regions
} }
pub fn cpus(&self) -> &Vec<u8> {
&self.cpus
}
pub fn cpus_mut(&mut self) -> &mut Vec<u8> {
&mut self.cpus
}
} }
pub type NumaNodes = BTreeMap<u32, NumaNode>; pub type NumaNodes = BTreeMap<u32, NumaNode>;
@ -356,6 +365,7 @@ impl MemoryManager {
node_id, node_id,
NumaNode { NumaNode {
memory_regions: vec![region.clone()], memory_regions: vec![region.clone()],
cpus: Vec::new(),
}, },
); );
} }
@ -1233,6 +1243,10 @@ impl MemoryManager {
pub fn numa_nodes(&self) -> &NumaNodes { pub fn numa_nodes(&self) -> &NumaNodes {
&self.numa_nodes &self.numa_nodes
} }
pub fn numa_nodes_mut(&mut self) -> &mut NumaNodes {
&mut self.numa_nodes
}
} }
#[cfg(feature = "acpi")] #[cfg(feature = "acpi")]

View File

@ -24,8 +24,8 @@ extern crate vm_allocator;
extern crate vm_memory; extern crate vm_memory;
use crate::config::{ use crate::config::{
DeviceConfig, DiskConfig, FsConfig, HotplugMethod, NetConfig, PmemConfig, ValidationError, DeviceConfig, DiskConfig, FsConfig, HotplugMethod, NetConfig, NumaConfig, PmemConfig,
VmConfig, VsockConfig, ValidationError, VmConfig, VsockConfig,
}; };
use crate::cpu; use crate::cpu;
use crate::device_manager::{self, get_win_size, Console, DeviceManager, DeviceManagerError}; use crate::device_manager::{self, get_win_size, Console, DeviceManager, DeviceManagerError};
@ -311,6 +311,11 @@ impl Vm {
.transpose() .transpose()
.map_err(Error::InitramfsFile)?; .map_err(Error::InitramfsFile)?;
// Update NUMA based on NumaConfig.
if let Some(numa_cfg) = config.lock().unwrap().numa.clone() {
Self::update_numa(numa_cfg, &memory_manager)?;
}
Ok(Vm { Ok(Vm {
kernel, kernel,
initramfs, initramfs,
@ -328,6 +333,24 @@ impl Vm {
}) })
} }
fn update_numa(
configs: Vec<NumaConfig>,
memory_manager: &Arc<Mutex<MemoryManager>>,
) -> Result<()> {
let mut mm = memory_manager.lock().unwrap();
let numa_nodes = mm.numa_nodes_mut();
for config in configs.iter() {
if let Some(cpus) = &config.cpus {
if let Some(node) = numa_nodes.get_mut(&config.id) {
node.cpus_mut().extend(cpus);
}
}
}
Ok(())
}
pub fn new( pub fn new(
config: Arc<Mutex<VmConfig>>, config: Arc<Mutex<VmConfig>>,
exit_evt: EventFd, exit_evt: EventFd,