Messages in this thread Patch in this message | | | Date | Tue, 14 May 2002 14:47:24 -0300 (BRT) | From | Rik van Riel <> | Subject | [PATCH] io wait statistics in /proc |
| |
Hi,
the following patch implements io wait statistics for the current 2.5 kernel, the patch works as follows:
1) every time a task has to sleep on IO it increments nr_iowait_tasks (in the slow path only)
2) in the timer interrupt we count a jiffy as iowait if it would otherwise have been counted as idle and there is a task sleeping on IO
3) to keep compatability with current procps iowait time is not substracted from idle time, programs like top can do this themselves once they get support for iowait
Please apply this patch for the next 2.5 kernel.
thank you,
Rik -- http://www.linuxsymposium.org/2002/ "You're one of those condescending OLS attendants" "Here's a nickle kid. Go buy yourself a real t-shirt"
http://www.surriel.com/ http://distro.conectiva.com/
fs/buffer.c | 2 ++ fs/proc/proc_misc.c | 13 ++++++++----- include/linux/kernel_stat.h | 3 ++- include/linux/swap.h | 1 + kernel/sched.c | 2 ++ mm/filemap.c | 5 +++++ 6 files changed, 20 insertions(+), 6 deletions(-)
===== fs/buffer.c 1.96 vs edited ===== --- 1.96/fs/buffer.c Sat May 4 20:46:31 2002 +++ edited/fs/buffer.c Tue May 14 14:06:40 2002 @@ -142,7 +142,9 @@ set_task_state(tsk, TASK_UNINTERRUPTIBLE); if (!buffer_locked(bh)) break; + atomic_inc(&nr_iowait_tasks); schedule(); + atomic_dec(&nr_iowait_tasks); } while (buffer_locked(bh)); tsk->state = TASK_RUNNING; remove_wait_queue(wq, &wait); ===== fs/proc/proc_misc.c 1.24 vs edited ===== --- 1.24/fs/proc/proc_misc.c Fri May 3 02:01:31 2002 +++ edited/fs/proc/proc_misc.c Tue May 14 14:06:41 2002 @@ -282,7 +282,7 @@ int i, len; extern unsigned long total_forks; unsigned long jif = jiffies; - unsigned int sum = 0, user = 0, nice = 0, system = 0; + unsigned int sum = 0, user = 0, nice = 0, system = 0, iowait = 0; int major, disk;
for (i = 0 ; i < smp_num_cpus; i++) { @@ -291,23 +291,26 @@ user += kstat.per_cpu_user[cpu]; nice += kstat.per_cpu_nice[cpu]; system += kstat.per_cpu_system[cpu]; + iowait += kstat.per_cpu_iowait[cpu]; #if !defined(CONFIG_ARCH_S390) for (j = 0 ; j < NR_IRQS ; j++) sum += kstat.irqs[cpu][j]; #endif }
- len = sprintf(page, "cpu %u %u %u %lu\n", user, nice, system, - jif * smp_num_cpus - (user + nice + system)); + len = sprintf(page, "cpu %u %u %u %lu %u\n", user, nice, system, + jif * smp_num_cpus - (user + nice + system), + iowait); for (i = 0 ; i < smp_num_cpus; i++) - len += sprintf(page + len, "cpu%d %u %u %u %lu\n", + len += sprintf(page + len, "cpu%d %u %u %u %lu %u\n", i, kstat.per_cpu_user[cpu_logical_map(i)], kstat.per_cpu_nice[cpu_logical_map(i)], kstat.per_cpu_system[cpu_logical_map(i)], jif - ( kstat.per_cpu_user[cpu_logical_map(i)] \ + kstat.per_cpu_nice[cpu_logical_map(i)] \ - + kstat.per_cpu_system[cpu_logical_map(i)])); + + kstat.per_cpu_system[cpu_logical_map(i)]), + kstat.per_cpu_iowait[cpu_logical_map(i)]); len += sprintf(page + len, "page %u %u\n" "swap %u %u\n" ===== include/linux/kernel_stat.h 1.4 vs edited ===== --- 1.4/include/linux/kernel_stat.h Thu Apr 11 01:25:39 2002 +++ edited/include/linux/kernel_stat.h Tue May 14 14:06:44 2002 @@ -18,7 +18,8 @@ struct kernel_stat { unsigned int per_cpu_user[NR_CPUS], per_cpu_nice[NR_CPUS], - per_cpu_system[NR_CPUS]; + per_cpu_system[NR_CPUS], + per_cpu_iowait[NR_CPUS]; unsigned int dk_drive[DK_MAX_MAJOR][DK_MAX_DISK]; unsigned int dk_drive_rio[DK_MAX_MAJOR][DK_MAX_DISK]; unsigned int dk_drive_wio[DK_MAX_MAJOR][DK_MAX_DISK]; ===== include/linux/swap.h 1.42 vs edited ===== --- 1.42/include/linux/swap.h Sun May 5 13:55:39 2002 +++ edited/include/linux/swap.h Tue May 14 14:07:52 2002 @@ -108,6 +108,7 @@ extern atomic_t buffermem_pages; extern spinlock_t pagecache_lock; extern void __remove_inode_page(struct page *); +extern atomic_t nr_iowait_tasks;
/* Incomplete types for prototype declarations: */ struct task_struct; ===== kernel/sched.c 1.73 vs edited ===== --- 1.73/kernel/sched.c Mon Apr 29 09:16:24 2002 +++ edited/kernel/sched.c Tue May 14 14:10:06 2002 @@ -679,6 +679,8 @@ if (p == rq->idle) { if (local_bh_count(cpu) || local_irq_count(cpu) > 1) kstat.per_cpu_system[cpu] += system; + else if (atomic_read(&nr_iowait_tasks) > 0) + kstat.per_cpu_iowait[cpu] += system; #if CONFIG_SMP idle_tick(); #endif ===== mm/filemap.c 1.87 vs edited ===== --- 1.87/mm/filemap.c Mon May 6 12:12:36 2002 +++ edited/mm/filemap.c Tue May 14 14:12:03 2002 @@ -48,6 +48,7 @@ * ->sb_lock (fs/fs-writeback.c) */ spinlock_t pagemap_lru_lock __cacheline_aligned_in_smp = SPIN_LOCK_UNLOCKED; +atomic_t nr_iowait_tasks = ATOMIC_INIT(0);
/* * Remove a page from the page cache and free it. Caller has to make @@ -611,8 +612,10 @@ set_task_state(tsk, TASK_UNINTERRUPTIBLE); if (!test_bit(bit_nr, &page->flags)) break; + atomic_inc(&nr_iowait_tasks); sync_page(page); schedule(); + atomic_dec(&nr_iowait_tasks); } while (test_bit(bit_nr, &page->flags)); __set_task_state(tsk, TASK_RUNNING); remove_wait_queue(waitqueue, &wait); @@ -675,8 +678,10 @@ for (;;) { set_task_state(tsk, TASK_UNINTERRUPTIBLE); if (PageLocked(page)) { + atomic_inc(&nr_iowait_tasks); sync_page(page); schedule(); + atomic_dec(&nr_iowait_tasks); } if (!TestSetPageLocked(page)) break; - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
| |