From c0d0d239327dd81667fc9b644e3b3cd678146251 Mon Sep 17 00:00:00 2001 From: Sebastien Boeuf Date: Mon, 31 Aug 2020 15:35:19 +0200 Subject: [PATCH] vmm: acpi: Introduce SLIT for NUMA nodes distances By introducing the SLIT (System Locality Distance Information Table), we provide the guest with the distance between each node. This lets the user describe the NUMA topology with a lot of details so that slower memory backing the VM can be exposed as being further away from other nodes. Signed-off-by: Sebastien Boeuf --- vmm/src/acpi.rs | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/vmm/src/acpi.rs b/vmm/src/acpi.rs index c7993c41d..fc73cfedf 100644 --- a/vmm/src/acpi.rs +++ b/vmm/src/acpi.rs @@ -150,12 +150,13 @@ pub fn create_acpi_tables( .expect("Error writing MCFG table"); tables.push(mcfg_offset.0); - // SRAT + // SRAT and SLIT // Only created if the NUMA nodes list is not empty. let numa_nodes = memory_manager.lock().unwrap().numa_nodes().clone(); let (prev_tbl_len, prev_tbl_off) = if numa_nodes.is_empty() { (mcfg.len(), mcfg_offset) } else { + // SRAT let mut srat = SDT::new(*b"SRAT", 36, 3, *b"CLOUDH", *b"CHSRAT ", 1); // SRAT reserved 12 bytes srat.append_slice(&[0u8; 12]); @@ -221,7 +222,34 @@ pub fn create_acpi_tables( .expect("Error writing SRAT table"); tables.push(srat_offset.0); - (srat.len(), srat_offset) + // SLIT + let mut slit = SDT::new(*b"SLIT", 36, 1, *b"CLOUDH", *b"CHSLIT ", 1); + // Number of System Localities on 8 bytes. + slit.append(numa_nodes.len() as u64); + + let existing_nodes: Vec = numa_nodes.keys().cloned().collect(); + for (node_id, node) in numa_nodes.iter() { + let distances = node.distances(); + for i in existing_nodes.iter() { + let dist: u8 = if *node_id == *i { + 10 + } else if let Some(distance) = distances.get(i) { + *distance as u8 + } else { + 20 + }; + + slit.append(dist); + } + } + + let slit_offset = srat_offset.checked_add(srat.len() as u64).unwrap(); + guest_mem + .write_slice(slit.as_slice(), slit_offset) + .expect("Error writing SRAT table"); + tables.push(slit_offset.0); + + (slit.len(), slit_offset) }; // XSDT