Home / Alt manpages / proc_interrupts(5)

  • proc_interrupts(5)
  • File format
  • linux

Read Per-CPU Interrupt Counts from /proc/interrupts

When one core is pegged and the rest sit idle, /proc/interrupts is where you go to find out which device is hammering it. This guide covers reading the live interrupt counters Linux exposes, working out which CPU is servicing a device, and comparing two samples without mistaking a huge lifetime counter for a fresh problem. You need a shell on the Linux host; the commands are read-only and normally need no elevated privileges. Allow about 10 minutes for a first pass.

What this file actually tells you

/proc/interrupts records interrupt counts for each CPU and I/O device, alongside internal kernel interrupt categories. On x86 and x86-64, the manpage specifically calls out entries such as NMI, the local timer, TLB flushes, rescheduling and remote function calls. The file is generated by procfs, so it always reflects the current kernel view rather than anything saved to disk.

The counters are cumulative. A large value only means many interrupts have been handled since the counter started, not that the device is consuming that much CPU right now. To talk about activity meaningfully, take two readings a known interval apart and compare the change.

1. Read the table

Print the file exactly as the kernel presents it:

cat /proc/interrupts

On a multi-CPU machine the first line names the CPU columns. A numbered line starts with an IRQ identifier, followed by one count per CPU, then kernel routing details and a device label. Labels and routing text vary by kernel, firmware, virtual machine and driver, so never write a parser that assumes a fixed number of trailing fields.

You will also see unnumbered names such as NMI, LOC, RES, CAL and TLB. These are not ordinary device IRQ numbers; they describe classes of interrupt internal to the system. A line full of zeroes is still useful: it shows the category exists on this kernel but simply has not accumulated a count yet.

Checkpoint

Confirm the header has the number of CPU columns you expect, and note whether the device you are investigating appears as a numbered IRQ line or a named internal category.

2. Find a device without losing its CPU distribution

Search for a stable device label while keeping the header for context. Replace DEVICE with a label visible in your own output:

grep -E 'CPU|DEVICE' /proc/interrupts

For example, this keeps the header and any line containing xhci, a common USB host-controller label:

grep -E 'CPU|xhci' /proc/interrupts

Read the counts across the row. If one CPU holds nearly all of a device's interrupts, that is a distribution observation, not proof of a problem on its own: IRQ affinity, the driver, workload and the host's interrupt-balancing policy can all shape it. Work out first whether the count is climbing quickly, and whether that same CPU is busy for an unrelated reason.

Never reuse a guessed IRQ number from another machine. IRQ assignments can shift after a reboot, a hardware change or a change in virtualisation configuration, so stick to the current label and current output.

3. Compare two snapshots

Take a first sample, wait briefly, then take a second. This pipeline prints the matching device lines at each point:

grep -E 'CPU|xhci' /proc/interrupts
sleep 5
grep -E 'CPU|xhci' /proc/interrupts

The second reading should show counters at least as large as the first, assuming the system keeps running normally. Subtract the first per-CPU row from the second to get interrupts handled during that five-second window. A row that has not moved may just represent an idle device. A row climbing fast is worth correlating with workload, CPU utilisation and logs before you touch any configuration.

For a quick view of numbered IRQ totals, this command sums only the initial numeric fields after the IRQ label. It is deliberately a rough inspection tool, not a universal parser:

awk 'NR > 1 && $1 ~ /^[0-9]+:$/ { total = 0; for (i = 2; i <= NF; i++) if ($i ~ /^[0-9]+$/) total += $i; print $1, total }' /proc/interrupts

It works on the table this host shows because per-CPU counts are numeric and the routing fields are not. A kernel with additional numeric fields could throw the total off, so for a precise device investigation, look at the original row instead of treating this sum as authoritative.

4. Handle misleading or missing readings

Seeing no output does not automatically mean the machine has no interrupts. Procfs can be restricted by a container, a different process namespace, or the environment the command runs in. Compare the command's environment against the host you actually mean to diagnose. The file itself is read-only, and changing its mode or trying to write to it will never configure interrupt handling.

Do not read a hardware failure into a high NMI, LOC, RES, CAL or TLB value on its own. These are lifetime totals and can run high on any busy, long-running system. Compare rates and corroborate against the device's actual behaviour. The reverse trap exists too: a low device count does not prove the device is healthy, since an idle device is often just idle, and an interrupt is only one part of a larger driver path.

This guide does not change IRQ affinity, disable an interrupt or restart a service. Those actions affect every user of a device and need their own evidence and recovery plan. If you later test a configuration change, save the current setting first, make one reversible change, and confirm the result with another pair of snapshots.

Done means

  • Displayed /proc/interrupts and identified its CPU columns.
  • Told numbered device rows apart from named internal interrupt categories.
  • Found the current row for a device instead of assuming an IRQ number.
  • Compared two readings over a measured interval and discussed a rate, not a raw total.
  • Kept observation separate from any risky change to interrupt routing or services.