(
configs: Option<&[NumaConfig]>,
memory_manager: &Arc<Mutex<MemoryManager>>,
)
| 1246 | } |
| 1247 | |
| 1248 | fn create_numa_nodes( |
| 1249 | configs: Option<&[NumaConfig]>, |
| 1250 | memory_manager: &Arc<Mutex<MemoryManager>>, |
| 1251 | ) -> Result<NumaNodes> { |
| 1252 | let mm = memory_manager.lock().unwrap(); |
| 1253 | let mm_zones = mm.memory_zones(); |
| 1254 | let mut numa_nodes = BTreeMap::new(); |
| 1255 | |
| 1256 | if let Some(configs) = &configs { |
| 1257 | for config in configs.iter() { |
| 1258 | if numa_nodes.contains_key(&config.guest_numa_id) { |
| 1259 | error!("Can't define twice the same NUMA node"); |
| 1260 | return Err(Error::InvalidNumaConfig); |
| 1261 | } |
| 1262 | |
| 1263 | let mut node = NumaNode::default(); |
| 1264 | |
| 1265 | if let Some(memory_zones) = &config.memory_zones { |
| 1266 | for memory_zone in memory_zones.iter() { |
| 1267 | if let Some(mm_zone) = mm_zones.get(memory_zone) { |
| 1268 | node.memory_regions.extend(mm_zone.regions().clone()); |
| 1269 | if let Some(virtiomem_zone) = mm_zone.virtio_mem_zone() { |
| 1270 | node.hotplug_regions.push(virtiomem_zone.region().clone()); |
| 1271 | } |
| 1272 | node.memory_zones.push(memory_zone.clone()); |
| 1273 | } else { |
| 1274 | error!("Unknown memory zone '{memory_zone}'"); |
| 1275 | return Err(Error::InvalidNumaConfig); |
| 1276 | } |
| 1277 | } |
| 1278 | } |
| 1279 | |
| 1280 | if let Some(cpus) = &config.cpus { |
| 1281 | node.cpus.extend(cpus); |
| 1282 | } |
| 1283 | |
| 1284 | if let Some(pci_segments) = &config.pci_segments { |
| 1285 | node.pci_segments.extend(pci_segments); |
| 1286 | } |
| 1287 | |
| 1288 | if let Some(distances) = &config.distances { |
| 1289 | for distance in distances.iter() { |
| 1290 | let dest = distance.destination; |
| 1291 | let dist = distance.distance; |
| 1292 | |
| 1293 | if dest == config.guest_numa_id && dist != 10 { |
| 1294 | warn!( |
| 1295 | "Ignoring self-distance {dest}@{dist} (must be 10 per ACPI spec)" |
| 1296 | ); |
| 1297 | } |
| 1298 | |
| 1299 | if !configs.iter().any(|cfg| cfg.guest_numa_id == dest) { |
| 1300 | error!("Unknown destination NUMA node {dest}"); |
| 1301 | return Err(Error::InvalidNumaConfig); |
| 1302 | } |
| 1303 | |
| 1304 | if node.distances.contains_key(&dest) { |
| 1305 | error!("Destination NUMA node {dest} has been already set"); |
nothing calls this directly
no test coverage detected