Skip to content

linux: treat a negative topology id as unavailable, not a parse error#421

Open
CodersAcademy006 wants to merge 1 commit into
pytorch:mainfrom
CodersAcademy006:fix/topology-id-negative-sentinel
Open

linux: treat a negative topology id as unavailable, not a parse error#421
CodersAcademy006 wants to merge 1 commit into
pytorch:mainfrom
CodersAcademy006:fix/topology-id-negative-sentinel

Conversation

@CodersAcademy006

Copy link
Copy Markdown

The kernel exposes core_id and physical_package_id as -1 when it has no topology information for a processor. Both are parsed with uint32_parser, which rejects any non-digit lead byte, so every such processor produces an error-level log claiming the sysfs file is malformed.

Observed on a native riscv64 board (SiFive U74-class, kernel 5.10.113), which reports core_id = -1 on all four cores:

Error in cpuinfo: failed to parse file /sys/devices/system/cpu/cpu0/topology/core_id: "-1" is not an unsigned number
Error in cpuinfo: failed to parse file /sys/devices/system/cpu/cpu1/topology/core_id: "-1" is not an unsigned number
Error in cpuinfo: failed to parse file /sys/devices/system/cpu/cpu2/topology/core_id: "-1" is not an unsigned number
Error in cpuinfo: failed to parse file /sys/devices/system/cpu/cpu3/topology/core_id: "-1" is not an unsigned number

-1 is a documented sentinel meaning "not populated", not corruption, so this is a false alarm rather than a real parse failure.

Root cause

parse_number (src/linux/processors.c) stops at the first non-digit. For -1 it stops immediately on the -, leaving parsed_end == text_start, which uint32_parser reports as "is not an unsigned number" at error level.

The change

Add a topology_id_parser wrapper used by the two topology getters. A topology id is never legitimately negative, so a leading - is reported as "value unavailable" at debug level instead. The return value is unchanged (false, since the id genuinely is unavailable), so no caller behavior changes. Only the false alarm goes away.

uint32_parser continues to back kernel_max and the three frequency getters, where a negative value would still be a genuine error.

physical_package_id parsed fine on the board above, but is exposed to the same sentinel through the same kernel mechanism, so it is covered for consistency.

Also fixed

The empty-file branch in uint32_parser hardcoded KERNEL_MAX_FILENAME even though the parser is shared by six call sites, so an empty core_id file would have blamed /sys/devices/system/cpu/kernel_max. It now reports the filename it was given.

Test plan

Compiled the real src/linux/processors.c into a harness driving its actual static parsers (stubbing only the sysfs reader), so this exercises the shipped code rather than a copy:

clang -DCPUINFO_LOG_LEVEL=5 -I src -I include -o t t.c src/log.c

Before, reproducing the board output exactly:

Error in cpuinfo: failed to parse file .../topology/core_id: "-1" is not an unsigned number
  core_id "-1"  -> ok=false
  core_id "0"   -> ok=true  value=0

After:

Debug (cpuinfo): file .../topology/core_id reports no topology information for this processor
  core_id "-1"  -> ok=false      (unchanged return, ERROR downgraded to DEBUG)
  core_id "0"   -> ok=true  value=0
  core_id "3"   -> ok=true  value=3
  core_id "-10" -> ok=false

The kernel exposes core_id and physical_package_id as -1 when it has no
topology information for a processor. Both were parsed with uint32_parser,
which rejects any non-digit lead byte, so every such processor produced an
error-level log claiming the sysfs file was malformed:

  Error in cpuinfo: failed to parse file
  /sys/devices/system/cpu/cpu0/topology/core_id: "-1" is not an unsigned number

-1 is a sentinel, not corruption. Parse it as "value unavailable" via a
topology_id_parser wrapper and log it at debug level. The return value is
unchanged (false, the id is genuinely unavailable), so no caller behavior
changes; only the false alarm goes away.

Observed on a native riscv64 board (SiFive U74-class, kernel 5.10.113),
which reports core_id -1 on all four cores. physical_package_id parsed fine
there, but is exposed to the same sentinel and is covered for consistency.

Also fixes uint32_parser's empty-file branch, which hardcoded
KERNEL_MAX_FILENAME while the parser is shared by six call sites, so an
empty core_id file would have blamed the wrong path.

Test Plan: compiled src/linux/processors.c into a harness driving the real
static parsers.

  clang -DCPUINFO_LOG_LEVEL=5 -I src -I include -o t t.c src/log.c

  before: core_id "-1" -> ok=false + ERROR "is not an unsigned number"
  after : core_id "-1" -> ok=false + DEBUG "reports no topology information"
          core_id "0"  -> ok=true  value=0
          core_id "3"  -> ok=true  value=3
@meta-cla meta-cla Bot added the cla signed label Jul 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant