From 09272b3c77464dad9cff9b8b30b59111d8b1b3cb Mon Sep 17 00:00:00 2001 From: mmc Date: Fri, 7 Aug 2026 12:09:47 -0500 Subject: [PATCH] lscpu: accept -1 as physical package id The kernel falls back to -1 in /sys/devices/system/cpu/cpuN/topology/physical_package_id when the architecture does not expose physical package information: https://www.kernel.org/doc/html/latest/admin-guide/cputopology.html Issue #495 reports exactly this on ppc64, where parsing the value as usize made lscpu panic. Parse it as i64 instead, so unknown ids collapse into a single socket bucket, matching the Socket(s): 1 that util-linux lscpu is observed to report there. Fixes #495 --- src/uu/lscpu/src/sysfs.rs | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/src/uu/lscpu/src/sysfs.rs b/src/uu/lscpu/src/sysfs.rs index e8a8e1a1..81ec12bb 100644 --- a/src/uu/lscpu/src/sysfs.rs +++ b/src/uu/lscpu/src/sysfs.rs @@ -18,7 +18,9 @@ pub struct CpuTopology { #[derive(Debug)] pub struct Cpu { _index: usize, - pub pkg_id: usize, + // i64 rather than usize: the kernel reports -1 when the architecture + // does not expose physical package information + pub pkg_id: i64, pub core_id: usize, pub caches: Vec, } @@ -53,7 +55,7 @@ impl CpuTopology { let pkg_id = fs::read_to_string(cpu_dir.join("topology/physical_package_id")) .unwrap() .trim() - .parse::() + .parse::() .unwrap(); let core_id = fs::read_to_string(cpu_dir.join("topology/core_id")) @@ -276,6 +278,31 @@ fn test_print_cache_size() { ); } +#[test] +fn test_socket_count_with_unknown_package_id() { + // The kernel reports physical_package_id as -1 when the architecture does + // not expose package information (e.g. some ppc64 machines, see #495). + // All-unknown ids collapse into a single socket bucket. + let topology = CpuTopology { + cpus: vec![ + Cpu { + _index: 0, + pkg_id: -1, + core_id: 0, + caches: vec![], + }, + Cpu { + _index: 1, + pkg_id: -1, + core_id: 1, + caches: vec![], + }, + ], + }; + assert_eq!(topology.socket_count(), 1); + assert_eq!(topology.core_count(), 2); +} + #[test] fn test_parse_cpu_list() { assert_eq!(parse_cpu_list(""), Vec::::new());