Skip to contentSkip to conversation

Add CPU state for iopoll

RFC In review Keith Busch 2 participants 4 messages Dec 31, 2015

Subsystems (4)
lore
Share & tools
lore
#0 lore raw

Hi everyone,

I'm just submitting to storage lists to see if anyone else thinks this is useful.

Linux kernel 4.4 adds a new block mode to poll IO for low-latency storage. When not polling, we can see CPU time spent in system vs. in iowait. For example, 'mpstat' may show:

  CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest   %idle
    0    0.00    0.00   40.96   59.04    0.00    0.00    0.00    0.00    0.00

and that's useful to see the iowait, and, when combined with other data, indicates how the h/w is performing. If we've enabled IO polling, though, we get something like this:

  CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest   %idle
    0    0.00    0.00  100.00    0.00    0.00    0.00    0.00    0.00    0.00

Which is pretty useless for gaining insights on how the h/w is doing. Right now I use 'perf record' to measure where CPU cycles are spent, but that's not always feasible or convenient.

The following series proposes a new CPU state called "iopoll" so we can get similarly useful information. The result looks like this:

CPU %usr %nice %sys %iowait %iopoll %irq %soft %steal %guest %gnice %idle

    0    1.00    0.00   34.00    0.00   65.00    0.00    0.00    0.00    0.00    0.00    0.00

The first patch is the kernel part. The second is for sysstat. I might be concerned about the potential for breaking older stats tools...

Thanks!

Keith Busch (1):
CPU: New state for iopoll

 block/blk-core.c            | 7 ++++++-
 fs/proc/stat.c              | 8 ++++++--
 include/linux/kernel_stat.h | 1 +
 include/linux/sched.h       | 1 +
 kernel/sched/cpuacct.c      | 1 +
 kernel/sched/cputime.c      | 7 ++++++-
 6 files changed, 21 insertions(+), 4 deletions(-)

Keith Busch (1):
sysstat: Report iopoll CPU percentage

 common.c   |  4 ++--
 iostat.c   | 10 ++++++----
 mpstat.c   | 18 ++++++++++++------
 rd_stats.c | 10 ++++++----
 rd_stats.h |  1 +
 5 files changed, 27 insertions(+), 16 deletions(-)
Signature · 1 line
2.6.2.307.g37023ba
#1 lore raw

RFC 1/1 CPU: New state for iopoll

This accounts for CPU time spent polling for IO seperately from system time.

Signed-off-by Keith Busch <keith.busch at intel.com>
---
 block/blk-core.c            | 7 ++++++-
 fs/proc/stat.c              | 8 ++++++--
 include/linux/kernel_stat.h | 1 +
 include/linux/sched.h       | 1 +
 kernel/sched/cpuacct.c      | 1 +
 kernel/sched/cputime.c      | 7 ++++++-
 6 files changed, 21 insertions(+), 4 deletions(-)
block/blk-core.c +6 -1
index 93810f2..b46fc2c 100644
@@ -3330,6 +3330,7 @@ bool blk_poll(struct request_queue *q, blk_qc_t cookie)
 	if (plug)
 		blk_flush_plug_list(plug, false);
 
+	current->in_iopoll = 1;
 	state = current->state;
 	while (!need_resched()) {
 		unsigned int queue_num = blk_qc_t_to_queue_num(cookie);
@@ -3342,19 +3343,23 @@ bool blk_poll(struct request_queue *q, blk_qc_t cookie)
 		if (ret > 0) {
 			hctx->poll_success++;
 			set_current_state(TASK_RUNNING);
+			current->in_iopoll = 0;
 			return true;
 		}
 
 		if (signal_pending_state(state, current))
 			set_current_state(TASK_RUNNING);
 
-		if (current->state == TASK_RUNNING)
+		if (current->state == TASK_RUNNING) {
+			current->in_iopoll = 0;
 			return true;
+		}
 		if (ret < 0)
 			break;
 		cpu_relax();
 	}
 
+	current->in_iopoll = 0;
 	return false;
 }
 
fs/proc/stat.c +6 -2
index 510413eb..5982efc 100644
@@ -81,14 +81,14 @@ static int show_stat(struct seq_file *p, void *v)
 {
 	int i, j;
 	unsigned long jif;
-	u64 user, nice, system, idle, iowait, irq, softirq, steal;
+	u64 user, nice, system, idle, iowait, iopoll, irq, softirq, steal;
 	u64 guest, guest_nice;
 	u64 sum = 0;
 	u64 sum_softirq = 0;
 	unsigned int per_softirq_sums[NR_SOFTIRQS] = {0};
 	struct timespec boottime;
 
-	user = nice = system = idle = iowait =
+	user = nice = system = idle = iowait = iopoll =
 		irq = softirq = steal = 0;
 	guest = guest_nice = 0;
 	getboottime(&boottime);
@@ -98,6 +98,7 @@ static int show_stat(struct seq_file *p, void *v)
 		user += kcpustat_cpu(i).cpustat[CPUTIME_USER];
 		nice += kcpustat_cpu(i).cpustat[CPUTIME_NICE];
 		system += kcpustat_cpu(i).cpustat[CPUTIME_SYSTEM];
+		iopoll += kcpustat_cpu(i).cpustat[CPUTIME_IOPOLL];
 		idle += get_idle_time(i);
 		iowait += get_iowait_time(i);
 		irq += kcpustat_cpu(i).cpustat[CPUTIME_IRQ];
@@ -128,6 +129,7 @@ static int show_stat(struct seq_file *p, void *v)
 	seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(steal));
 	seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(guest));
 	seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(guest_nice));
+	seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(iopoll));
 	seq_putc(p, '\n');
 
 	for_each_online_cpu(i) {
@@ -135,6 +137,7 @@ static int show_stat(struct seq_file *p, void *v)
 		user = kcpustat_cpu(i).cpustat[CPUTIME_USER];
 		nice = kcpustat_cpu(i).cpustat[CPUTIME_NICE];
 		system = kcpustat_cpu(i).cpustat[CPUTIME_SYSTEM];
+		iopoll = kcpustat_cpu(i).cpustat[CPUTIME_IOPOLL];
 		idle = get_idle_time(i);
 		iowait = get_iowait_time(i);
 		irq = kcpustat_cpu(i).cpustat[CPUTIME_IRQ];
@@ -153,6 +156,7 @@ static int show_stat(struct seq_file *p, void *v)
 		seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(steal));
 		seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(guest));
 		seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(guest_nice));
+		seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(iopoll));
 		seq_putc(p, '\n');
 	}
 	seq_printf(p, "intr %llu", (unsigned long long)sum);
include/linux/kernel_stat.h +1 -0
index 25a822f..c092745 100644
@@ -28,6 +28,7 @@ enum cpu_usage_stat {
 	CPUTIME_STEAL,
 	CPUTIME_GUEST,
 	CPUTIME_GUEST_NICE,
+	CPUTIME_IOPOLL,
 	NR_STATS,
 };
 
include/linux/sched.h +1 -0
index edad7a4..b34830e 100644
@@ -1458,6 +1458,7 @@ struct task_struct {
 	unsigned in_execve:1;	/* Tell the LSMs that the process is doing an
 				 * execve */
 	unsigned in_iowait:1;
+	unsigned in_iopoll:1;
 
 	/* Revert to default priority/policy when forking */
 	unsigned sched_reset_on_fork:1;
kernel/sched/cpuacct.c +1 -0
index dd7cbb5..5ad3ad4 100644
@@ -200,6 +200,7 @@ static int cpuacct_stats_show(struct seq_file *sf, void *v)
 	for_each_online_cpu(cpu) {
 		struct kernel_cpustat *kcpustat = per_cpu_ptr(ca->cpustat, cpu);
 		val += kcpustat->cpustat[CPUTIME_SYSTEM];
+		val += kcpustat->cpustat[CPUTIME_IOPOLL];
 		val += kcpustat->cpustat[CPUTIME_IRQ];
 		val += kcpustat->cpustat[CPUTIME_SOFTIRQ];
 	}
kernel/sched/cputime.c +6 -1
index 05de80b..887c1a9 100644
@@ -222,6 +222,8 @@ void account_system_time(struct task_struct *p, int hardirq_offset,
 		index = CPUTIME_IRQ;
 	else if (in_serving_softirq())
 		index = CPUTIME_SOFTIRQ;
+	else if (p->in_iopoll)
+		index = CPUTIME_IOPOLL;
 	else
 		index = CPUTIME_SYSTEM;
 
@@ -367,7 +369,10 @@ static void irqtime_account_process_tick(struct task_struct *p, int user_tick,
 	} else if (p->flags & PF_VCPU) { /* System time or guest time */
 		account_guest_time(p, cputime, scaled);
 	} else {
-		__account_system_time(p, cputime, scaled,	CPUTIME_SYSTEM);
+		if (p->in_iopoll)
+			__account_system_time(p, cputime, scaled, CPUTIME_IOPOLL);
+		else
+			__account_system_time(p, cputime, scaled, CPUTIME_SYSTEM);
 	}
 }
 
Signature · 1 line
2.6.2.307.g37023ba
#2 lore raw

[RFC] CPU: New state for iopoll

This is really goods do helpful, thanks Keith

Sent from my iPhone

Quoted 174 lines · Keith Busch

This accounts for CPU time spent polling for IO seperately from system time.

Signed-off-by Keith Busch <keith.busch at intel.com>

---

block/blk-core.c            | 7 ++++++-
fs/proc/stat.c              | 8 ++++++--
include/linux/kernel_stat.h | 1 +
include/linux/sched.h       | 1 +
kernel/sched/cpuacct.c      | 1 +
kernel/sched/cputime.c      | 7 ++++++-
6 files changed, 21 insertions(+), 4 deletions(-)
block/blk-core.c +6 -1
index 93810f2..b46fc2c 100644
@@ -3330,6 +3330,7 @@ bool blk_poll(struct request_queue *q, blk_qc_t cookie)
   if (plug)
       blk_flush_plug_list(plug, false);
 
+    current->in_iopoll = 1;
   state = current->state;
   while (!need_resched()) {
       unsigned int queue_num = blk_qc_t_to_queue_num(cookie);
@@ -3342,19 +3343,23 @@ bool blk_poll(struct request_queue *q, blk_qc_t cookie)
       if (ret > 0) {
           hctx->poll_success++;
           set_current_state(TASK_RUNNING);
+            current->in_iopoll = 0;
           return true;
       }
 
       if (signal_pending_state(state, current))
           set_current_state(TASK_RUNNING);
 
-        if (current->state == TASK_RUNNING)
+        if (current->state == TASK_RUNNING) {
+            current->in_iopoll = 0;
           return true;
+        }
       if (ret < 0)
           break;
       cpu_relax();
   }
 
+    current->in_iopoll = 0;
   return false;
 }
 
fs/proc/stat.c +6 -2
index 510413eb..5982efc 100644
@@ -81,14 +81,14 @@ static int show_stat(struct seq_file *p, void *v)
 {
   int i, j;
   unsigned long jif;
-    u64 user, nice, system, idle, iowait, irq, softirq, steal;
+    u64 user, nice, system, idle, iowait, iopoll, irq, softirq, steal;
   u64 guest, guest_nice;
   u64 sum = 0;
   u64 sum_softirq = 0;
   unsigned int per_softirq_sums[NR_SOFTIRQS] = {0};
   struct timespec boottime;
 
-    user = nice = system = idle = iowait =
+    user = nice = system = idle = iowait = iopoll =
       irq = softirq = steal = 0;
   guest = guest_nice = 0;
   getboottime(&boottime);
@@ -98,6 +98,7 @@ static int show_stat(struct seq_file *p, void *v)
       user += kcpustat_cpu(i).cpustat[CPUTIME_USER];
       nice += kcpustat_cpu(i).cpustat[CPUTIME_NICE];
       system += kcpustat_cpu(i).cpustat[CPUTIME_SYSTEM];
+        iopoll += kcpustat_cpu(i).cpustat[CPUTIME_IOPOLL];
       idle += get_idle_time(i);
       iowait += get_iowait_time(i);
       irq += kcpustat_cpu(i).cpustat[CPUTIME_IRQ];
@@ -128,6 +129,7 @@ static int show_stat(struct seq_file *p, void *v)
   seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(steal));
   seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(guest));
   seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(guest_nice));
+    seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(iopoll));
   seq_putc(p, '\n');
 
   for_each_online_cpu(i) {
@@ -135,6 +137,7 @@ static int show_stat(struct seq_file *p, void *v)
       user = kcpustat_cpu(i).cpustat[CPUTIME_USER];
       nice = kcpustat_cpu(i).cpustat[CPUTIME_NICE];
       system = kcpustat_cpu(i).cpustat[CPUTIME_SYSTEM];
+        iopoll = kcpustat_cpu(i).cpustat[CPUTIME_IOPOLL];
       idle = get_idle_time(i);
       iowait = get_iowait_time(i);
       irq = kcpustat_cpu(i).cpustat[CPUTIME_IRQ];
@@ -153,6 +156,7 @@ static int show_stat(struct seq_file *p, void *v)
       seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(steal));
       seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(guest));
       seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(guest_nice));
+        seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(iopoll));
       seq_putc(p, '\n');
   }
   seq_printf(p, "intr %llu", (unsigned long long)sum);
include/linux/kernel_stat.h +1 -0
index 25a822f..c092745 100644
@@ -28,6 +28,7 @@ enum cpu_usage_stat {
   CPUTIME_STEAL,
   CPUTIME_GUEST,
   CPUTIME_GUEST_NICE,
+    CPUTIME_IOPOLL,
   NR_STATS,
 };
 
include/linux/sched.h +1 -0
index edad7a4..b34830e 100644
@@ -1458,6 +1458,7 @@ struct task_struct {
   unsigned in_execve:1;    /* Tell the LSMs that the process is doing an
                * execve */
   unsigned in_iowait:1;
+    unsigned in_iopoll:1;
 
   /* Revert to default priority/policy when forking */
   unsigned sched_reset_on_fork:1;
kernel/sched/cpuacct.c +1 -0
index dd7cbb5..5ad3ad4 100644
@@ -200,6 +200,7 @@ static int cpuacct_stats_show(struct seq_file *sf, void *v)
   for_each_online_cpu(cpu) {
       struct kernel_cpustat *kcpustat = per_cpu_ptr(ca->cpustat, cpu);
       val += kcpustat->cpustat[CPUTIME_SYSTEM];
+        val += kcpustat->cpustat[CPUTIME_IOPOLL];
       val += kcpustat->cpustat[CPUTIME_IRQ];
       val += kcpustat->cpustat[CPUTIME_SOFTIRQ];
   }
kernel/sched/cputime.c +6 -1
index 05de80b..887c1a9 100644
@@ -222,6 +222,8 @@ void account_system_time(struct task_struct *p, int hardirq_offset,
       index = CPUTIME_IRQ;
   else if (in_serving_softirq())
       index = CPUTIME_SOFTIRQ;
+    else if (p->in_iopoll)
+        index = CPUTIME_IOPOLL;
   else
       index = CPUTIME_SYSTEM;
 
@@ -367,7 +369,10 @@ static void irqtime_account_process_tick(struct task_struct *p, int user_tick,
   } else if (p->flags & PF_VCPU) { /* System time or guest time */
       account_guest_time(p, cputime, scaled);
   } else {
-        __account_system_time(p, cputime, scaled,    CPUTIME_SYSTEM);
+        if (p->in_iopoll)
+            __account_system_time(p, cputime, scaled, CPUTIME_IOPOLL);
+        else
+            __account_system_time(p, cputime, scaled, CPUTIME_SYSTEM);
   }
 }
 
Signature · 7 lines
2.6.2.307.g37023ba


_______________________________________________
Linux-nvme mailing list
Linux-nvme at lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-nvme
#3 lore raw

RFC 1/1 sysstat: Report iopoll CPU percentage

In reply to Keith Busch
Signed-off-by Keith Busch <keith.busch at intel.com>
---
 common.c   |  4 ++--
 iostat.c   | 10 ++++++----
 mpstat.c   | 18 ++++++++++++------
 rd_stats.c | 10 ++++++----
 rd_stats.h |  1 +
 5 files changed, 27 insertions(+), 16 deletions(-)
common.c +2 -2
index 2510f67..1f3fb3e 100644
@@ -605,11 +605,11 @@ unsigned long long get_per_cpu_interval(struct stats_cpu *scc,
 	 * because cpu_user and cpu_nice already include them.
 	 */
 	return ((scc->cpu_user    + scc->cpu_nice   +
-		 scc->cpu_sys     + scc->cpu_iowait +
+		 scc->cpu_sys     + scc->cpu_iowait + scc->cpu_iopoll +
 		 scc->cpu_idle    + scc->cpu_steal  +
 		 scc->cpu_hardirq + scc->cpu_softirq) -
 		(scp->cpu_user    + scp->cpu_nice   +
-		 scp->cpu_sys     + scp->cpu_iowait +
+		 scp->cpu_sys     + scp->cpu_iowait + scp->cpu_iopoll +
 		 scp->cpu_idle    + scp->cpu_steal  +
 		 scp->cpu_hardirq + scp->cpu_softirq) +
 		 ishift);
iostat.c +6 -4
index 4bf0342..eb0e906 100644
@@ -824,10 +824,10 @@ void compute_device_groups_stats(int curr)
  */
 void write_cpu_stat(int curr, unsigned long long itv)
 {
-	printf("avg-cpu:  %%user   %%nice %%system %%iowait  %%steal   %%idle\n");
+	printf("avg-cpu:  %%user   %%nice %%system %%iowait %%iopoll %%steal   %%idle\n");
 
 	printf("       ");
-	cprintf_pc(6, 7, 2,
+	cprintf_pc(7, 7, 2,
 		   ll_sp_value(st_cpu[!curr]->cpu_user,   st_cpu[curr]->cpu_user,   itv),
 		   ll_sp_value(st_cpu[!curr]->cpu_nice,   st_cpu[curr]->cpu_nice,   itv),
 		   /*
@@ -839,6 +839,7 @@ void write_cpu_stat(int curr, unsigned long long itv)
 			       st_cpu[curr]->cpu_sys + st_cpu[curr]->cpu_softirq +
 			       st_cpu[curr]->cpu_hardirq, itv),
 		   ll_sp_value(st_cpu[!curr]->cpu_iowait, st_cpu[curr]->cpu_iowait, itv),
+		   ll_sp_value(st_cpu[!curr]->cpu_iopoll,   st_cpu[curr]->cpu_iopoll, itv),
 		   ll_sp_value(st_cpu[!curr]->cpu_steal,  st_cpu[curr]->cpu_steal,  itv),
 		   (st_cpu[curr]->cpu_idle < st_cpu[!curr]->cpu_idle) ?
 		   0.0 :
@@ -1088,7 +1089,7 @@ void write_stats(int curr, struct tm *rectime)
 			fprintf(stderr, "itv=%llu st_cpu[curr]{ cpu_user=%llu cpu_nice=%llu "
 					"cpu_sys=%llu cpu_idle=%llu cpu_iowait=%llu cpu_steal=%llu "
 					"cpu_hardirq=%llu cpu_softirq=%llu cpu_guest=%llu "
-					"cpu_guest_nice=%llu }\n",
+					"cpu_guest_nice=%llu cpu_io_poll:%llu}\n",
 				itv,
 				st_cpu[curr]->cpu_user,
 				st_cpu[curr]->cpu_nice,
@@ -1099,7 +1100,8 @@ void write_stats(int curr, struct tm *rectime)
 				st_cpu[curr]->cpu_hardirq,
 				st_cpu[curr]->cpu_softirq,
 				st_cpu[curr]->cpu_guest,
-				st_cpu[curr]->cpu_guest_nice);
+				st_cpu[curr]->cpu_guest_nice,
+				st_cpu[curr]->cpu_iopoll);
 		}
 #endif
 
mpstat.c +12 -6
index 3b62aa0..5d642e7 100644
@@ -227,7 +227,7 @@ void write_cpu_stats(int dis, unsigned long long g_itv, int prev, int curr,
 	int cpu;
 
 	if (dis) {
-		printf("\n%-11s  CPU    %%usr   %%nice    %%sys %%iowait    %%irq   "
+		printf("\n%-11s  CPU    %%usr   %%nice    %%sys %%iowait %%iopoll   %%irq   "
 		       "%%soft  %%steal  %%guest  %%gnice   %%idle\n",
 		       prev_string);
 	}
@@ -238,7 +238,7 @@ void write_cpu_stats(int dis, unsigned long long g_itv, int prev, int curr,
 		printf("%-11s", curr_string);
 		cprintf_in(IS_STR, " %s", " all", 0);
 
-		cprintf_pc(10, 7, 2,
+		cprintf_pc(11, 7, 2,
 			   (st_cpu[curr]->cpu_user - st_cpu[curr]->cpu_guest) <
 			   (st_cpu[prev]->cpu_user - st_cpu[prev]->cpu_guest) ?
 			   0.0 :
@@ -257,6 +257,9 @@ void write_cpu_stats(int dis, unsigned long long g_itv, int prev, int curr,
 			   ll_sp_value(st_cpu[prev]->cpu_iowait,
 				       st_cpu[curr]->cpu_iowait,
 				       g_itv),
+			   ll_sp_value(st_cpu[prev]->cpu_iopoll,
+				       st_cpu[curr]->cpu_iopoll,
+				       g_itv),
 			   ll_sp_value(st_cpu[prev]->cpu_hardirq,
 				       st_cpu[curr]->cpu_hardirq,
 				       g_itv),
@@ -302,8 +305,8 @@ void write_cpu_stats(int dis, unsigned long long g_itv, int prev, int curr,
 			if (!DISPLAY_ONLINE_CPU(flags)) {
 				printf("%-11s", curr_string);
 				cprintf_in(IS_INT, " %4d", "", cpu - 1);
-				cprintf_pc(10, 7, 2,
-					   0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
+				cprintf_pc(11, 7, 2,
+					   0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
 				printf("\n");
 			}
 			continue;
@@ -320,13 +323,13 @@ void write_cpu_stats(int dis, unsigned long long g_itv, int prev, int curr,
 			 * If the CPU is tickless then there is no change in CPU values
 			 * but the sum of values is not zero.
 			 */
-			cprintf_pc(10, 7, 2,
+			cprintf_pc(11, 7, 2,
 				   0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 100.0);
 			printf("\n");
 		}
 
 		else {
-			cprintf_pc(10, 7, 2,
+			cprintf_pc(11, 7, 2,
 				   (scc->cpu_user - scc->cpu_guest) < (scp->cpu_user - scp->cpu_guest) ?
 				   0.0 :
 				   ll_sp_value(scp->cpu_user - scp->cpu_guest,
@@ -343,6 +346,9 @@ void write_cpu_stats(int dis, unsigned long long g_itv, int prev, int curr,
 				   ll_sp_value(scp->cpu_iowait,
 					       scc->cpu_iowait,
 					       pc_itv),
+				   ll_sp_value(scp->cpu_iopoll,
+					       scc->cpu_iopoll,
+					       pc_itv),
 				   ll_sp_value(scp->cpu_hardirq,
 					       scc->cpu_hardirq,
 					       pc_itv),
rd_stats.c +6 -4
index 009b770..364cb29 100644
@@ -85,7 +85,7 @@ void read_stat_cpu(struct stats_cpu *st_cpu, int nbr,
 			 * (user, nice, etc.) among all proc. CPU usage is not reduced
 			 * to one processor to avoid rounding problems.
 			 */
-			sscanf(line + 5, "%llu %llu %llu %llu %llu %llu %llu %llu %llu %llu",
+			sscanf(line + 5, "%llu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu",
 			       &st_cpu->cpu_user,
 			       &st_cpu->cpu_nice,
 			       &st_cpu->cpu_sys,
@@ -95,7 +95,8 @@ void read_stat_cpu(struct stats_cpu *st_cpu, int nbr,
 			       &st_cpu->cpu_softirq,
 			       &st_cpu->cpu_steal,
 			       &st_cpu->cpu_guest,
-			       &st_cpu->cpu_guest_nice);
+			       &st_cpu->cpu_guest_nice,
+			       &st_cpu->cpu_iopoll);
 
 			/*
 			 * Compute the uptime of the system in jiffies (1/100ths of a second
@@ -120,7 +121,7 @@ void read_stat_cpu(struct stats_cpu *st_cpu, int nbr,
 				 * (user, nice, etc) for current proc.
 				 * This is done only on SMP machines.
 				 */
-				sscanf(line + 3, "%d %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu",
+				sscanf(line + 3, "%d %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu",
 				       &proc_nb,
 				       &sc.cpu_user,
 				       &sc.cpu_nice,
@@ -131,7 +132,8 @@ void read_stat_cpu(struct stats_cpu *st_cpu, int nbr,
 				       &sc.cpu_softirq,
 				       &sc.cpu_steal,
 				       &sc.cpu_guest,
-				       &sc.cpu_guest_nice);
+				       &sc.cpu_guest_nice,
+				       &sc.cpu_iopoll);
 
 				if (proc_nb < (nbr - 1)) {
 					st_cpu_i = st_cpu + proc_nb + 1;
rd_stats.h +1 -0
index decec04..392d67a 100644
@@ -88,6 +88,7 @@ struct stats_cpu {
 	unsigned long long cpu_sys		__attribute__ ((aligned (16)));
 	unsigned long long cpu_idle		__attribute__ ((aligned (16)));
 	unsigned long long cpu_iowait		__attribute__ ((aligned (16)));
+	unsigned long long cpu_iopoll		__attribute__ ((aligned (16)));
 	unsigned long long cpu_steal		__attribute__ ((aligned (16)));
 	unsigned long long cpu_hardirq		__attribute__ ((aligned (16)));
 	unsigned long long cpu_softirq		__attribute__ ((aligned (16)));
Signature · 1 line
2.6.2.307.g37023ba