From 9ecc75029c8555385ee534337dfb3786a97656de Mon Sep 17 00:00:00 2001 From: R Aadarsh Date: Mon, 15 Jun 2026 09:32:15 +0530 Subject: [PATCH] * Correctly put cpus and memories for adoption * Test on x86_64 (works) --- src/acpi/slit.rs | 5 +---- src/acpi/srat/mod.rs | 6 ++++-- src/acpi/srat/x86.rs | 1 - src/numa.rs | 31 ++++++++++++++++++++----------- 4 files changed, 25 insertions(+), 18 deletions(-) diff --git a/src/acpi/slit.rs b/src/acpi/slit.rs index efe5fdf545..d5c45acfbe 100644 --- a/src/acpi/slit.rs +++ b/src/acpi/slit.rs @@ -27,15 +27,12 @@ impl Slit { for i in 0..ndom { for j in i..ndom { + // ignore distances from a domain to itself, since it is always 10 if i != j { unsafe { numa::set_distance(i, j, unsafe { *address.add((i + ndom * j) as usize) }); numa::set_distance(j, i, unsafe { *address.add((i + ndom * j) as usize) }); } - } else { - unsafe { - numa::set_distance(i, j, 10); - } } } } diff --git a/src/acpi/srat/mod.rs b/src/acpi/srat/mod.rs index 29935257ad..ef9484076b 100644 --- a/src/acpi/srat/mod.rs +++ b/src/acpi/srat/mod.rs @@ -76,7 +76,7 @@ impl<'a> Iterator for SratIter<'a> { assert!(entry_len as usize == size_of::() + 2); *(entry.add(2) as *const GiccAffinity) }), - // ignore ITS Affinity and Generic Initiator Affinity + // ignore GIC ITS Affinity and Generic Initiator Affinity 4 | 5 => { self.i += entry_len as u32; continue; @@ -96,7 +96,9 @@ pub enum SratEntry { MemoryAffinity(MemoryAffinity), ProcessorLocalAffinity(ProcessorLocalAffinity), GiccAffinity(GiccAffinity), - Unknown(u8), // unimplemented: Generic Initiator Affinity; our current focus is only on memory and cpus + // unimplemented: Gic Its Affinity and Generic Initiator Affinity + // our current focus is only on memory and cpus + Unknown(u8), } #[repr(C, packed)] diff --git a/src/acpi/srat/x86.rs b/src/acpi/srat/x86.rs index 49c2545c40..484e8a2e69 100644 --- a/src/acpi/srat/x86.rs +++ b/src/acpi/srat/x86.rs @@ -61,5 +61,4 @@ pub fn init_srat(srat: &Srat) { _ => continue, } } - println!("{:?}", NUMA_NODES.get().unwrap()); } diff --git a/src/numa.rs b/src/numa.rs index e46fd9285f..edf09746cf 100644 --- a/src/numa.rs +++ b/src/numa.rs @@ -39,6 +39,7 @@ pub struct NumaNode { pub fn init() { NUMA_NODES.call_once(|| HashMap::new()); + let mut flag = false; #[cfg(all( feature = "acpi", @@ -47,12 +48,14 @@ pub fn init() { { acpi::srat::init(); acpi::slit::init(); - return; + flag = true; } #[cfg(any(target_arch = "riscv64", target_arch = "aarch64"))] { - todo!() + if !flag { + todo!() + } } unsafe { @@ -68,7 +71,6 @@ pub fn init() { pub unsafe fn add_cpu(id: u32, node_id: u32) { let numa_nodes = NUMA_NODES.get().unwrap(); - /* 💀💀💀 HIGHLY UNSAFE 💀💀💀 */ let numa_nodes = unsafe { &mut *(&raw const *numa_nodes as *mut HashMap) }; if let Some(node) = numa_nodes.get_mut(&id) { @@ -90,7 +92,6 @@ pub unsafe fn add_cpu(id: u32, node_id: u32) { pub unsafe fn add_memory(node_id: u32, start: usize, length: usize) { let numa_nodes = NUMA_NODES.get().unwrap(); - /* 💀💀💀 HIGHLY UNSAFE 💀💀💀 */ let numa_nodes = unsafe { &mut *(&raw const *numa_nodes as *mut HashMap) }; if let Some(node) = numa_nodes.get_mut(&node_id) { @@ -110,7 +111,6 @@ pub unsafe fn add_memory(node_id: u32, start: usize, length: usize) { } pub unsafe fn set_distance(src: u32, target: u32, distance: u8) { - /* 💀💀💀 HIGHLY UNSAFE 💀💀💀 */ let nodes = unsafe { &mut *(&raw const *(NUMA_NODES.get().unwrap()) as *mut HashMap) }; @@ -119,7 +119,6 @@ pub unsafe fn set_distance(src: u32, target: u32, distance: u8) { } unsafe fn shrink() { - /* 💀💀💀 HIGHLY UNSAFE 💀💀💀 */ let nodes = unsafe { &mut *(&raw const *(NUMA_NODES.get().unwrap()) as *mut HashMap) }; @@ -138,7 +137,6 @@ unsafe fn shrink() { /// /// See the comment above the definition of `NumaNode`. unsafe fn reorganise() { - /* 💀💀💀 HIGHLY UNSAFE 💀💀💀 */ let nodes = unsafe { &mut *(&raw const *(NUMA_NODES.get().unwrap()) as *mut HashMap) }; let ids = nodes.keys().map(|e| *e).collect::>(); @@ -147,7 +145,10 @@ unsafe fn reorganise() { let node = nodes.remove(&id).unwrap(); if node.cpus.len() == 0 { - put_for_adoption(nodes, node.distances, Some(node.memory), None); + assert!(node.memory.len() != 0); + put_for_adoption(nodes, node.distances, Some(node.memory), None, id); + } else if node.memory.len() == 0 { + put_for_adoption(nodes, node.distances, None, Some(node.cpus), id); } else { nodes.insert(id, node); } @@ -159,22 +160,30 @@ fn put_for_adoption( distances: Vec<(u32, u8)>, memories: Option>, cpus: Option>, + orphan_node_id: u32, ) { if let Some(memories) = memories { assert!(cpus.is_none()); - let (nearest_node_id, _) = distances.first().unwrap(); + let (nearest_node_id, distance) = distances.first().unwrap(); let nearest_node = nodes.get_mut(nearest_node_id).unwrap(); nearest_node.memory.extend(memories); } else if let Some(cpus) = cpus { assert!(memories.is_none()); - let (nearest_node_id, _) = distances.first().unwrap(); + let (nearest_node_id, distance) = distances.first().unwrap(); let nearest_node = nodes.get_mut(nearest_node_id).unwrap(); nearest_node.cpus.extend(cpus); + } else { + panic!() + }; + + for (_, node) in nodes { + if let Some(idx) = node.distances.iter().position(|e| e.0 == orphan_node_id) { + let _ = node.distances.remove(idx); + } } } unsafe fn sort_by_distances() { - /* 💀💀💀 HIGHLY UNSAFE 💀💀💀 */ let nodes = unsafe { &mut *(&raw const *(NUMA_NODES.get().unwrap()) as *mut HashMap) };