Skip to content

sysfs: bound cpufreq attribute reads with a deadline - #861

Open
waterWang wants to merge 1 commit into
prometheus:masterfrom
waterWang:fix-cpufreq-read-timeout
Open

sysfs: bound cpufreq attribute reads with a deadline#861
waterWang wants to merge 1 commit into
prometheus:masterfrom
waterWang:fix-cpufreq-read-timeout

Conversation

@waterWang

Copy link
Copy Markdown

Problem

On arm64 systems with cppc_cpufreq, reads of cpufreq sysfs attributes (e.g. scaling_cur_freq) go through the PCC firmware mailbox. When the firmware never answers, os.ReadFile blocks forever. Because SystemCpufreq reads every policy in parallel via errgroup, one stuck read hangs the whole collector and leaks a goroutine plus a file descriptor on every scrape.

Fixes prometheus/node_exporter#3791

Fix

Add readCpufreqFile — a helper that opens the sysfs attribute, sets a 5-second read deadline via SetReadDeadline, and reads with io.ReadAll. The deadline aborts the blocked read when the firmware never responds, so the collector can never hang forever.

Timed-out reads are treated like a missing/permission-denied attribute (skipped), so the remaining CPUs still produce metrics and node_scrape_collector_success stays 1.

A fallback path preserves the original blocking read for file types that do not support deadlines (regular files), which do not exhibit the firmware-hang behaviour.

Changes

  • sysfs/system_cpu.go: new readCpufreqFile helper + cpufreqReadTimeout constant; parseCpufreqCpuinfo uses it instead of util.ReadUintFromFile, util.SysReadFile, and util.ReadFileNoStat.
  • sysfs/system_cpu_test.go: TestReadCpufreqFileTimeout exercises the deadline-abort path with a pipe/FIFO.

Verification

  • go build ./sysfs/ (GOOS=linux)
  • go vet ./sysfs/
  • go test -c ./sysfs/ (test binary compiles)
  • Deadline logic verified on macOS with os.Pipe + SetReadDeadline — blocked read returns i/o timeout error within 300ms.

Closes prometheus/node_exporter#3791.

On arm64 systems with cppc_cpufreq, reads of cpufreq sysfs attributes
(e.g. scaling_cur_freq) go through the PCC firmware mailbox. When the
firmware never answers, os.ReadFile blocks forever; because
SystemCpufreq reads every policy in parallel via errgroup, one stuck
read hangs the whole collector and leaks a goroutine plus a file
descriptor on every scrape.

Bound every per-policy attribute read with a 5s deadline via
SetReadDeadline. Timed-out reads are treated like a missing/permission
attribute (skipped), so the remaining CPUs still produce metrics and
node_scrape_collector_success stays 1.

Fixes prometheus/node_exporter#3791.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

cpufreq collector hangs forever on arm64 with cppc_cpufreq, leaking a goroutine and an fd per scrape

1 participant