comprehensive cleanup: remove dead code in cpufreqd, iommu, numad
Three Red Bear-original daemons had dead code that the compiler
flagged. Removed it; the fix is purely deletional — no functionality
changed.
cpufreqd (local/recipes/system/cpufreqd/source/src/main.rs):
- Remove unused EPP constants (PERFORMANCE, BALANCE_PERFORMANCE,
BALANCE_POWER, POWERSAVE). The HWP request builder uses an inline
formula rather than these named values.
- Remove the unused IA32_PERF_STATUS constant and the
read_current_pstate helper. The current P-state readback path
was dormant (the dwell-counter hysteresis replaced it).
- Remove the unused 'unsafe' block from the cpuid_hypervisor_bit
call. The core::arch::x86_64::__cpuid_count intrinsic is itself
an unsafe fn — the outer block was redundant.
- Remove unused PState.latency_us field and PState struct literal
initializers in read_acpi_pss and the static fallback. The field
was never read.
- Remove unused CpuInfo.hwp_guaranteed and hwp_efficient fields
and the corresponding read_hwp_capabilities destructuring. The
fields were never read after the initial extraction.
iommu (local/recipes/system/iommu/source/src/interrupt.rs):
- Add #[allow(dead_code)] to InterruptRemapTable.buffer. The field
is the RAII holder for the DMA buffer allocated by
new_allocated; the field is never read but Drop releases the
allocation. A docstring documents the RAII intent so a future
maintainer does not 'clean up' the unused field and leak the
allocation.
numad (local/recipes/system/numad/source/src/main.rs):
- Remove SLIT collection: the daemon only reads SRAT and the
collected SLIT bytes were assigned but never parsed. Removing
the collection (signatures, branches, and buffer) eliminates
the dead store. The SLIT_SIGNATURE constant goes with it.
- Remove unused MAX_NUMA_NODES constant.
- Remove unused SratMemory struct (SRAT Memory Affinity entry
layout). The daemon only handles SratProcessorApic today.
- Remove dead w[4].parse() call in read_acpi_pss. The latency_us
field it was populating is gone; the parse returned an unused
Result<_, _> that needed a type annotation to compile.
Builds:
cargo check (host target)
cpufreqd 0 warnings
numad 0 warnings
iommu 0 warnings
cargo check --target x86_64-unknown-redox
cpufreqd 0 warnings
numad 0 warnings
iommu 0 warnings
Tests: redbear-hid-core was added in an unrelated recent commit
(rl-module); out of scope here.
This commit is contained in:
@@ -6,17 +6,10 @@ use log::{info, warn, LevelFilter};
|
||||
|
||||
// MSR addresses — see Intel SDM Vol 3B §14
|
||||
const IA32_PERF_CTL: u32 = 0x199; // legacy P-state
|
||||
const IA32_PERF_STATUS: u32 = 0x198; // current P-state (read-only)
|
||||
const IA32_HWP_REQUEST: u32 = 0x774; // HWP control
|
||||
const IA32_HWP_CAPABILITIES: u32 = 0x771; // HWP range
|
||||
const IA32_PM_ENABLE: u32 = 0x770; // HWP enable bit
|
||||
|
||||
// EPP values for IA32_HWP_REQUEST[31:24]
|
||||
const EPP_PERFORMANCE: u64 = 0x00;
|
||||
const EPP_BALANCE_PERFORMANCE: u64 = 0x80;
|
||||
const EPP_BALANCE_POWER: u64 = 0xC0;
|
||||
const EPP_POWERSAVE: u64 = 0xFF;
|
||||
|
||||
// Hysteresis: minimum dwell time (in polls) at the current P-state
|
||||
// before we consider changing. Prevents thrashing at the
|
||||
// Ondemand/Conservative boundaries when load oscillates around the
|
||||
@@ -54,7 +47,6 @@ enum PstateMode { LegacyPerfCtl, Hwp }
|
||||
struct PState {
|
||||
freq_khz: u32,
|
||||
power_mw: u32,
|
||||
latency_us: u32,
|
||||
ctl: u64,
|
||||
}
|
||||
|
||||
@@ -80,8 +72,6 @@ struct CpuInfo {
|
||||
mode: PstateMode,
|
||||
hwp_min: u8, // from MSR 0x771[15:8]
|
||||
hwp_max: u8, // from MSR 0x771[7:0]
|
||||
hwp_guaranteed: u8, // from MSR 0x771[23:16]
|
||||
hwp_efficient: u8, // from MSR 0x771[31:24]
|
||||
/// Number of consecutive polls at the current_idx. Reset to
|
||||
/// 0 on every state change. The next P-state transition
|
||||
/// only fires when dwell reaches DWELL_POLLS. This is the
|
||||
@@ -159,18 +149,22 @@ fn read_acpi_pss(cpu: u32) -> Vec<PState> {
|
||||
for l in d.lines() {
|
||||
let w: Vec<&str> = l.split_whitespace().collect();
|
||||
if w.len() >= 6 {
|
||||
if let (Ok(f), Ok(pw), Ok(la), Ok(ct)) =
|
||||
(w[0].parse(), w[2].parse(), w[4].parse(), u64::from_str_radix(w[5], 16))
|
||||
{ s.push(PState { freq_khz: f, power_mw: pw, latency_us: la, ctl: ct }); }
|
||||
if let (Ok(f), Ok(pw), Ok(ct)) = (
|
||||
w[0].parse(),
|
||||
w[2].parse(),
|
||||
u64::from_str_radix(w[5], 16),
|
||||
) {
|
||||
s.push(PState { freq_khz: f, power_mw: pw, ctl: ct });
|
||||
}
|
||||
}
|
||||
}
|
||||
if !s.is_empty() { return s; }
|
||||
}
|
||||
vec![
|
||||
PState { freq_khz: 2400, power_mw: 35000, latency_us: 10, ctl: 0x1a00 },
|
||||
PState { freq_khz: 2000, power_mw: 25000, latency_us: 10, ctl: 0x1600 },
|
||||
PState { freq_khz: 1600, power_mw: 18000, latency_us: 10, ctl: 0x1200 },
|
||||
PState { freq_khz: 1200, power_mw: 12000, latency_us: 10, ctl: 0x0e00 },
|
||||
PState { freq_khz: 2400, power_mw: 35000, ctl: 0x1a00 },
|
||||
PState { freq_khz: 2000, power_mw: 25000, ctl: 0x1600 },
|
||||
PState { freq_khz: 1600, power_mw: 18000, ctl: 0x1200 },
|
||||
PState { freq_khz: 1200, power_mw: 12000, ctl: 0x0e00 },
|
||||
]
|
||||
}
|
||||
|
||||
@@ -180,26 +174,6 @@ fn write_msr(cpu: u32, msr: u32, val: u64) -> bool {
|
||||
.map(|mut f| f.write_all(&val.to_ne_bytes()).is_ok()).unwrap_or(false)
|
||||
}
|
||||
|
||||
/// Read the current operating P-state index from IA32_PERF_STATUS
|
||||
/// (MSR 0x198). The state occupies bits [3:0] of the 64-bit read.
|
||||
/// Returns None if the read fails or the value is reserved (>15).
|
||||
///
|
||||
/// This is the "readback" that prevents the P0->P1->P0 oscillation
|
||||
/// seen on QEMU: the MSR write to IA32_PERF_CTL silently succeeds
|
||||
/// (PIIX4 emulation in QEMU) but the CPU never actually changes
|
||||
/// state, so reading IA32_PERF_STATUS back returns the unchanged
|
||||
/// P0. We use that to detect the no-op and short-circuit the
|
||||
/// governor's next transition until something actually changes.
|
||||
fn read_current_pstate(cpu: u32) -> Option<u8> {
|
||||
let path = format!("/scheme/sys/msr/{}/0x{:x}", cpu, IA32_PERF_STATUS);
|
||||
let mut f = fs::File::open(&path).ok()?;
|
||||
let mut buf = [0u8; 8];
|
||||
f.read_exact(&mut buf).ok()?;
|
||||
let val = u64::from_le_bytes(buf);
|
||||
let pstate = (val & 0xF) as u8;
|
||||
if pstate > 15 { None } else { Some(pstate) }
|
||||
}
|
||||
|
||||
/// Map a P-state index to IA32_HWP_REQUEST value.
|
||||
/// IA32_HWP_REQUEST layout (Vol 3B §14.4.4):
|
||||
/// [7:0] Minimum Performance
|
||||
@@ -393,7 +367,7 @@ fn cpuid_hypervisor_bit() -> bool {
|
||||
// hypervisor-present bit. Returns true when running under
|
||||
// any hypervisor that advertises itself (QEMU/KVM, VMware,
|
||||
// VirtualBox, Hyper-V, Xen, bhyve, etc.).
|
||||
let cpuid = unsafe { core::arch::x86_64::__cpuid_count(1, 0) };
|
||||
let cpuid = core::arch::x86_64::__cpuid_count(1, 0);
|
||||
(cpuid.ecx & (1 << 31)) != 0
|
||||
}
|
||||
|
||||
@@ -420,19 +394,20 @@ fn main() {
|
||||
info!("detected {} CPU(s), governor={:?}", cpus.len(), governor);
|
||||
let mut ci: Vec<CpuInfo> = cpus.iter().map(|&id| {
|
||||
let mode = detect_pstate_mode(id);
|
||||
let (hwp_min, hwp_max, hwp_guaranteed, hwp_efficient) = if mode == PstateMode::Hwp {
|
||||
read_hwp_capabilities(id)
|
||||
let (hwp_min, hwp_max) = if mode == PstateMode::Hwp {
|
||||
let (min, max, _, _) = read_hwp_capabilities(id);
|
||||
(min, max)
|
||||
} else {
|
||||
(0, 0, 0, 0)
|
||||
(0, 0)
|
||||
};
|
||||
if mode == PstateMode::Hwp {
|
||||
info!("CPU{}: HWP active (range {}-{}, EPP cap {}-{})", id, hwp_min, hwp_max, hwp_efficient, hwp_guaranteed);
|
||||
info!("CPU{}: HWP active (range {}-{})", id, hwp_min, hwp_max);
|
||||
} else {
|
||||
info!("CPU{}: legacy P-states (HWP not enabled)", id);
|
||||
}
|
||||
let ps = read_acpi_pss(id);
|
||||
info!("CPU{}: {} P-states ({} - {} kHz)", id, ps.len(), ps.first().map_or(0, |p| p.freq_khz), ps.last().map_or(0, |p| p.freq_khz));
|
||||
CpuInfo { id, pstates: ps, current_idx: 0, load_history: [0.0; SAMPLE_WINDOW], load_idx: 0, throttle: false, msr_errors: 0, msr_suppressed: false, mode, hwp_min, hwp_max, hwp_guaranteed, hwp_efficient, dwell: 0, dwell_target: 0, read_only: virtualized }
|
||||
CpuInfo { id, pstates: ps, current_idx: 0, load_history: [0.0; SAMPLE_WINDOW], load_idx: 0, throttle: false, msr_errors: 0, msr_suppressed: false, mode, hwp_min, hwp_max, dwell: 0, dwell_target: 0, read_only: virtualized }
|
||||
}).collect();
|
||||
let mut prev: Vec<(u64, u64)> = vec![(0, 0); cpus.len()];
|
||||
let mut thermal = ThermalCache::new();
|
||||
|
||||
@@ -43,6 +43,11 @@ impl Irte {
|
||||
|
||||
pub struct InterruptRemapTable {
|
||||
pub entries: usize,
|
||||
/// RAII holder for the DMA buffer allocated by `new_allocated`.
|
||||
/// The field is never read; the buffer is kept alive so the
|
||||
/// allocation lives as long as the table. Dropping the table
|
||||
/// releases the underlying DMA pages.
|
||||
#[allow(dead_code)]
|
||||
buffer: Option<DmaBuffer>,
|
||||
base: usize,
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/// numad — Red Bear OS NUMA topology daemon
|
||||
///
|
||||
/// Reads ACPI SRAT/SLIT from physical memory via /scheme/memory/physical
|
||||
/// Reads ACPI SRAT from physical memory via /scheme/memory/physical
|
||||
/// and feeds NUMA topology hints to the kernel for scheduler placement.
|
||||
use std::fs;
|
||||
use std::io::{Read, Write};
|
||||
@@ -8,8 +8,6 @@ use std::mem;
|
||||
|
||||
const RSDP_SIGNATURE: &[u8; 8] = b"RSD PTR ";
|
||||
const SRAT_SIGNATURE: &[u8; 4] = b"SRAT";
|
||||
const SLIT_SIGNATURE: &[u8; 4] = b"SLIT";
|
||||
const MAX_NUMA_NODES: usize = 8;
|
||||
|
||||
#[repr(C, packed)]
|
||||
#[derive(Copy, Clone)]
|
||||
@@ -54,19 +52,6 @@ struct SratProcessorApic {
|
||||
clock_domain: u32,
|
||||
}
|
||||
|
||||
#[repr(C, packed)]
|
||||
#[derive(Copy, Clone)]
|
||||
struct SratMemory {
|
||||
entry: SratEntry,
|
||||
proximity_domain: u32,
|
||||
reserved: u16,
|
||||
base_address: u64,
|
||||
length: u64,
|
||||
reserved2: [u8; 8],
|
||||
flags: u32,
|
||||
reserved3: [u8; 8],
|
||||
}
|
||||
|
||||
struct NumaNode {
|
||||
id: u8,
|
||||
apic_ids: Vec<u8>,
|
||||
@@ -96,7 +81,6 @@ fn main() {
|
||||
let entries_base = sdt_addr + mem::size_of::<SdtHeader>();
|
||||
|
||||
let mut srat_data: Option<Vec<u8>> = None;
|
||||
let mut slit_data: Option<Vec<u8>> = None;
|
||||
|
||||
for i in 0..num_entries {
|
||||
let entry_addr = entries_base + i * 4;
|
||||
@@ -106,14 +90,8 @@ fn main() {
|
||||
continue;
|
||||
}
|
||||
let header = read_phys::<SdtHeader>(table_addr);
|
||||
match &header.signature {
|
||||
SRAT_SIGNATURE => {
|
||||
srat_data = Some(read_phys_bytes(table_addr, header.length as usize));
|
||||
}
|
||||
SLIT_SIGNATURE => {
|
||||
slit_data = Some(read_phys_bytes(table_addr, header.length as usize));
|
||||
}
|
||||
_ => {}
|
||||
if &header.signature == SRAT_SIGNATURE {
|
||||
srat_data = Some(read_phys_bytes(table_addr, header.length as usize));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user