Patchwork [3.5.yuz,extended,stable] Patch "nohz: Fix idle ticks in cpu summary line of /proc/stat" has been added to staging queue

mail settings
Submitter Herton Ronaldo Krzesinski
Date Nov. 22, 2012, 4:45 a.m.
Message ID <>
Download mbox | patch
Permalink /patch/200934/
State New
Headers show


Herton Ronaldo Krzesinski - Nov. 22, 2012, 4:45 a.m.
This is a note to let you know that I have just added a patch titled

    nohz: Fix idle ticks in cpu summary line of /proc/stat

to the linux-3.5.y-queue branch of the 3.5.yuz extended stable tree 
which can be found at:;a=shortlog;h=refs/heads/linux-3.5.y-queue

If you, or anyone else, feels it should not be added to this tree, please 
reply to this email.

For more information about the 3.5.yuz tree, see



From 378cbb4a911105fbfcfa5560ee54ae4f14d72141 Mon Sep 17 00:00:00 2001
From: Michal Hocko <>
Date: Wed, 10 Oct 2012 11:51:09 +0530
Subject: [PATCH] nohz: Fix idle ticks in cpu summary line of /proc/stat

commit 7386cdbf2f57ea8cff3c9fde93f206e58b9fe13f upstream.

Git commit 09a1d34f8535ecf9 "nohz: Make idle/iowait counter update
conditional" introduced a bug in regard to cpu hotplug. The effect is
that the number of idle ticks in the cpu summary line in /proc/stat is
still counting ticks for offline cpus.

Reproduction is easy, just start a workload that keeps all cpus busy,
switch off one or more cpus and then watch the idle field in top.
On a dual-core with one cpu 100% busy and one offline cpu you will get
something like this:

%Cpu(s): 48.7 us,  1.3 sy,  0.0 ni, 50.0 id,  0.0 wa,  0.0 hi,  0.0 si,
%0.0 st

The problem is that an offline cpu still has ts->idle_active == 1.
To fix this we should make sure that the cpu is online when calling
get_cpu_idle_time_us and get_cpu_iowait_time_us.

[Srivatsa: Rebased to current mainline]

Reported-by: Martin Schwidefsky <>
Signed-off-by: Michal Hocko <>
Reviewed-by: Srivatsa S. Bhat <>
Signed-off-by: Srivatsa S. Bhat <>
Signed-off-by: Thomas Gleixner <>
Signed-off-by: Herton Ronaldo Krzesinski <>
 fs/proc/stat.c |   14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)



diff --git a/fs/proc/stat.c b/fs/proc/stat.c
index 64c3b31..e296572 100644
--- a/fs/proc/stat.c
+++ b/fs/proc/stat.c
@@ -45,10 +45,13 @@  static cputime64_t get_iowait_time(int cpu)

 static u64 get_idle_time(int cpu)
-	u64 idle, idle_time = get_cpu_idle_time_us(cpu, NULL);
+	u64 idle, idle_time = -1ULL;
+	if (cpu_online(cpu))
+		idle_time = get_cpu_idle_time_us(cpu, NULL);

 	if (idle_time == -1ULL)
-		/* !NO_HZ so we can rely on cpustat.idle */
+		/* !NO_HZ or cpu offline so we can rely on cpustat.idle */
 		idle = kcpustat_cpu(cpu).cpustat[CPUTIME_IDLE];
 		idle = usecs_to_cputime64(idle_time);
@@ -58,10 +61,13 @@  static u64 get_idle_time(int cpu)

 static u64 get_iowait_time(int cpu)
-	u64 iowait, iowait_time = get_cpu_iowait_time_us(cpu, NULL);
+	u64 iowait, iowait_time = -1ULL;
+	if (cpu_online(cpu))
+		iowait_time = get_cpu_iowait_time_us(cpu, NULL);

 	if (iowait_time == -1ULL)
-		/* !NO_HZ so we can rely on cpustat.iowait */
+		/* !NO_HZ or cpu offline so we can rely on cpustat.iowait */
 		iowait = kcpustat_cpu(cpu).cpustat[CPUTIME_IOWAIT];
 		iowait = usecs_to_cputime64(iowait_time);