Fundamentals 13 min read

Understanding Linux CPU Utilization Statistics and the Top Command

This article explains how Linux calculates CPU utilization shown by the top command, detailing the role of /proc/stat, kernel sampling mechanisms, and the handling of user, nice, system, IRQ, soft‑IRQ, iowait and idle times, while providing code examples and practical insights.

Refining Core Development Skills
Refining Core Development Skills
Refining Core Development Skills
Understanding Linux CPU Utilization Statistics and the Top Command

When monitoring a server, most people start with the top command to view overall CPU usage, but the calculation behind the displayed percentages is not trivial. This article first encourages readers to think about the problem of measuring CPU utilization on a four‑core server running four processes, highlighting the need for accuracy and second‑level granularity.

It then examines how the top command obtains its data from the /proc/stat pseudo‑file. The kernel exposes CPU counters via the proc_stat_operations file operations, which invoke stat_open , single_open_size , and ultimately show_stat to format the values.

# strace top
... 
openat(AT_FDCWD, "/proc/stat", O_RDONLY) = 4
openat(AT_FDCWD, "/proc/2351514/stat", O_RDONLY) = 8
...

The show_stat function iterates over each possible CPU, aggregates fields from the per‑CPU kernel_cpustat structure, and prints them as tick counts using seq_put_decimal_ull . These tick counts are later converted to percentages by top after reading two snapshots (t1 and t2) and performing simple arithmetic.

Linux updates these counters via a periodic timer interrupt defined by CONFIG_HZ (commonly 1000 Hz, i.e., 1 ms). Each timer tick calls update_process_times , which delegates to account_process_tick and then to specific accounting functions based on the execution context.

void update_process_times(int user_tick) {
    struct task_struct *p = current;
    account_process_tick(p, user_tick);
    ...
}

account_user_time adds time to either the user or nice field depending on the process's nice value, while account_system_time distributes time among irq , softirq , or system based on interrupt context. Idle time is handled by account_idle_time , which distinguishes between pure idle and I/O‑wait states.

void account_idle_time(u64 cputime) {
    if (atomic_read(&rq->nr_iowait) > 0)
        cpustat[CPUTIME_IOWAIT] += cputime;
    else
        cpustat[CPUTIME_IDLE] += cputime;
}

By accumulating these per‑tick values in the per‑CPU kernel_cpustat structure, Linux can provide a reasonably accurate, though sampled, view of CPU usage. The article concludes that while the method is not 100 % precise due to sampling, it is sufficient for most monitoring purposes, and it offers a simple shell script (linked on GitHub) for practical experimentation.

Kernelsystem monitoringCPU utilizationproc stattop command
Refining Core Development Skills
Written by

Refining Core Development Skills

Fei has over 10 years of development experience at Tencent and Sogou. Through this account, he shares his deep insights on performance.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.