45e086558e
- Fix P15-8-init-cycle-detection.patch: replace visiting+error with seen+silent-skip to eliminate 11 false-positive 'dependency cycle detected' errors on shared deps - Fix P0-daemon-fix-init-notify-unwrap.patch: remove eprintln! for missing INIT_NOTIFY (expected for oneshot_async services, ~7 daemons affected) - Fix driver-manager hotplug loop: add PERMANENTLY_SKIPPED static set shared between hotplug handler and DriverConfig::probe() to stop infinite re-probing of Fatal/NotSupported/deferred-exhausted device+driver pairs (e.g. ided) - Fix driver-manager log_timeline: suppress repeated EPIPE/ENOENT errors with AtomicI32 dedup and AtomicBool one-shot guards for boot timeline JSON - Add driver-manager SIGTERM handler, ACPI bus registration, --status mode, driver reap loop, graceful shutdown, and reduced deferred retries (30→3)
84 lines
3.8 KiB
Diff
84 lines
3.8 KiB
Diff
--- a/src/acpi/madt/arch/x86.rs
|
|
+++ b/src/acpi/madt/arch/x86.rs
|
|
@@ -150,15 +150,16 @@
|
|
let stack_start = RmmA::phys_to_virt(alloc.base()).data();
|
|
let stack_end = stack_start + (PAGE_SIZE << 4);
|
|
|
|
- let next_cpu = crate::CPU_COUNT.load(Ordering::Relaxed);
|
|
- if next_cpu >= crate::cpu_set::MAX_CPU_COUNT {
|
|
+ // Atomically allocate a CPU ID — fetch_add is SeqCst so that
|
|
+ // all later stores (PercpuBlock, NUMA node) are ordered after.
|
|
+ let cpu_id = LogicalCpuId::new(crate::CPU_COUNT.fetch_add(1, Ordering::SeqCst));
|
|
+ if cpu_id.get() >= crate::cpu_set::MAX_CPU_COUNT {
|
|
println!(
|
|
"KERNEL AP: CPU {} exceeds logical CPU limit, skipping",
|
|
ap_local_apic.id
|
|
);
|
|
continue;
|
|
}
|
|
- let cpu_id = LogicalCpuId::new(next_cpu);
|
|
|
|
let pcr_ptr = crate::arch::gdt::allocate_and_init_pcr(cpu_id, stack_end);
|
|
|
|
@@ -184,8 +185,10 @@
|
|
#[expect(clippy::fn_to_numeric_cast)]
|
|
ap_code.write(kstart_ap as u64);
|
|
|
|
- // TODO: Is this necessary (this fence)?
|
|
- core::arch::asm!("");
|
|
+ // Ensure all trampoline writes are visible to the AP before
|
|
+ // it starts executing. asm!("") is only a compiler barrier;
|
|
+ // fence(SeqCst) is a full hardware memory barrier.
|
|
+ core::sync::atomic::fence(Ordering::SeqCst);
|
|
};
|
|
AP_READY.store(false, Ordering::SeqCst);
|
|
|
|
@@ -241,8 +244,6 @@
|
|
continue;
|
|
}
|
|
|
|
- crate::CPU_COUNT.fetch_add(1, Ordering::Relaxed);
|
|
-
|
|
// Record APIC→CPU mapping for NUMA topology.
|
|
unsafe {
|
|
record_apic_mapping(u32::from(ap_local_apic.id), cpu_id);
|
|
@@ -273,15 +274,16 @@
|
|
let stack_start = RmmA::phys_to_virt(alloc.base()).data();
|
|
let stack_end = stack_start + (PAGE_SIZE << 4);
|
|
|
|
- let next_cpu = crate::CPU_COUNT.load(Ordering::Relaxed);
|
|
- if next_cpu >= crate::cpu_set::MAX_CPU_COUNT {
|
|
+ // Atomically allocate a CPU ID — fetch_add is SeqCst so that
|
|
+ // all later stores (PercpuBlock, NUMA node) are ordered after.
|
|
+ let cpu_id = LogicalCpuId::new(crate::CPU_COUNT.fetch_add(1, Ordering::SeqCst));
|
|
+ if cpu_id.get() >= crate::cpu_set::MAX_CPU_COUNT {
|
|
println!(
|
|
"KERNEL AP: CPU {} exceeds logical CPU limit, skipping",
|
|
apic_id
|
|
);
|
|
continue;
|
|
}
|
|
- let cpu_id = LogicalCpuId::new(next_cpu);
|
|
|
|
let pcr_ptr = crate::arch::gdt::allocate_and_init_pcr(cpu_id, stack_end);
|
|
let idt_ptr = crate::arch::idt::allocate_and_init_idt(cpu_id);
|
|
@@ -304,7 +306,8 @@
|
|
ap_page_table.write(page_table_physaddr as u64);
|
|
#[expect(clippy::fn_to_numeric_cast)]
|
|
ap_code.write(kstart_ap as u64);
|
|
- core::arch::asm!("");
|
|
+ // Ensure all trampoline writes are visible to the AP.
|
|
+ core::sync::atomic::fence(Ordering::SeqCst);
|
|
}
|
|
AP_READY.store(false, Ordering::SeqCst);
|
|
|
|
@@ -362,8 +365,6 @@
|
|
continue;
|
|
}
|
|
|
|
- crate::CPU_COUNT.fetch_add(1, Ordering::Relaxed);
|
|
-
|
|
// Record APIC→CPU mapping for NUMA topology.
|
|
unsafe {
|
|
record_apic_mapping(apic_id, cpu_id);
|