aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArjan van de Ven <arjan@linux.intel.com>2009-07-20 14:26:58 -0400
committerIngo Molnar <mingo@elte.hu>2009-09-02 02:44:08 -0400
commit8f0dfc34e9b323a028c2ec41abb7e9de477b7a94 (patch)
treefa7e44d9ad3eb22517f0724e71f9812f71a16ae2
parentf14eff1cc2f418a7c5e23aedc6a1bdca3343b871 (diff)
sched: Provide iowait counters
For counting how long an application has been waiting for (disk) IO, there currently is only the HZ sample driven information available, while for all other counters in this class, a high resolution version is available via CONFIG_SCHEDSTATS. In order to make an improved bootchart tool possible, we also need a higher resolution version of the iowait time. This patch below adds this scheduler statistic to the kernel. Signed-off-by: Arjan van de Ven <arjan@linux.intel.com> Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl> LKML-Reference: <4A64B813.1080506@linux.intel.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
-rw-r--r--include/linux/sched.h4
-rw-r--r--kernel/sched.c4
-rw-r--r--kernel/sched_debug.c4
-rw-r--r--kernel/sched_fair.c5
4 files changed, 17 insertions, 0 deletions
diff --git a/include/linux/sched.h b/include/linux/sched.h
index e209ae0e7a8a..9c96ef2f7e68 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -1111,6 +1111,8 @@ struct sched_entity {
1111 u64 wait_max; 1111 u64 wait_max;
1112 u64 wait_count; 1112 u64 wait_count;
1113 u64 wait_sum; 1113 u64 wait_sum;
1114 u64 iowait_count;
1115 u64 iowait_sum;
1114 1116
1115 u64 sleep_start; 1117 u64 sleep_start;
1116 u64 sleep_max; 1118 u64 sleep_max;
@@ -1231,6 +1233,8 @@ struct task_struct {
1231 unsigned did_exec:1; 1233 unsigned did_exec:1;
1232 unsigned in_execve:1; /* Tell the LSMs that the process is doing an 1234 unsigned in_execve:1; /* Tell the LSMs that the process is doing an
1233 * execve */ 1235 * execve */
1236 unsigned in_iowait:1;
1237
1234 1238
1235 /* Revert to default priority/policy when forking */ 1239 /* Revert to default priority/policy when forking */
1236 unsigned sched_reset_on_fork:1; 1240 unsigned sched_reset_on_fork:1;
diff --git a/kernel/sched.c b/kernel/sched.c
index 6244d24cafc1..38d05a89e0f2 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -6754,7 +6754,9 @@ void __sched io_schedule(void)
6754 6754
6755 delayacct_blkio_start(); 6755 delayacct_blkio_start();
6756 atomic_inc(&rq->nr_iowait); 6756 atomic_inc(&rq->nr_iowait);
6757 current->in_iowait = 1;
6757 schedule(); 6758 schedule();
6759 current->in_iowait = 0;
6758 atomic_dec(&rq->nr_iowait); 6760 atomic_dec(&rq->nr_iowait);
6759 delayacct_blkio_end(); 6761 delayacct_blkio_end();
6760} 6762}
@@ -6767,7 +6769,9 @@ long __sched io_schedule_timeout(long timeout)
6767 6769
6768 delayacct_blkio_start(); 6770 delayacct_blkio_start();
6769 atomic_inc(&rq->nr_iowait); 6771 atomic_inc(&rq->nr_iowait);
6772 current->in_iowait = 1;
6770 ret = schedule_timeout(timeout); 6773 ret = schedule_timeout(timeout);
6774 current->in_iowait = 0;
6771 atomic_dec(&rq->nr_iowait); 6775 atomic_dec(&rq->nr_iowait);
6772 delayacct_blkio_end(); 6776 delayacct_blkio_end();
6773 return ret; 6777 return ret;
diff --git a/kernel/sched_debug.c b/kernel/sched_debug.c
index 70c7e0b79946..5ddbd0891267 100644
--- a/kernel/sched_debug.c
+++ b/kernel/sched_debug.c
@@ -409,6 +409,8 @@ void proc_sched_show_task(struct task_struct *p, struct seq_file *m)
409 PN(se.wait_max); 409 PN(se.wait_max);
410 PN(se.wait_sum); 410 PN(se.wait_sum);
411 P(se.wait_count); 411 P(se.wait_count);
412 PN(se.iowait_sum);
413 P(se.iowait_count);
412 P(sched_info.bkl_count); 414 P(sched_info.bkl_count);
413 P(se.nr_migrations); 415 P(se.nr_migrations);
414 P(se.nr_migrations_cold); 416 P(se.nr_migrations_cold);
@@ -479,6 +481,8 @@ void proc_sched_set_task(struct task_struct *p)
479 p->se.wait_max = 0; 481 p->se.wait_max = 0;
480 p->se.wait_sum = 0; 482 p->se.wait_sum = 0;
481 p->se.wait_count = 0; 483 p->se.wait_count = 0;
484 p->se.iowait_sum = 0;
485 p->se.iowait_count = 0;
482 p->se.sleep_max = 0; 486 p->se.sleep_max = 0;
483 p->se.sum_sleep_runtime = 0; 487 p->se.sum_sleep_runtime = 0;
484 p->se.block_max = 0; 488 p->se.block_max = 0;
diff --git a/kernel/sched_fair.c b/kernel/sched_fair.c
index 342000b31ad6..471fa281f5e0 100644
--- a/kernel/sched_fair.c
+++ b/kernel/sched_fair.c
@@ -652,6 +652,11 @@ static void enqueue_sleeper(struct cfs_rq *cfs_rq, struct sched_entity *se)
652 se->sum_sleep_runtime += delta; 652 se->sum_sleep_runtime += delta;
653 653
654 if (tsk) { 654 if (tsk) {
655 if (tsk->in_iowait) {
656 se->iowait_sum += delta;
657 se->iowait_count++;
658 }
659
655 /* 660 /*
656 * Blocking time is in units of nanosecs, so shift by 661 * Blocking time is in units of nanosecs, so shift by
657 * 20 to get a milliseconds-range estimation of the 662 * 20 to get a milliseconds-range estimation of the