Returns io info for all visible processes. The data is the same as /proc/[pid]/io but formatted as a series of numbers on a single line. A PID column is also prepended. Signed-off-by: Eugene Lubarsky <elubarsky.linux@xxxxxxxxx> --- fs/proc/base.c | 66 ++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 59 insertions(+), 7 deletions(-) diff --git a/fs/proc/base.c b/fs/proc/base.c index 5982fd43dd21..03d48225b6d1 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -2910,9 +2910,8 @@ static const struct file_operations proc_coredump_filter_operations = { #endif #ifdef CONFIG_TASK_IO_ACCOUNTING -static int do_io_accounting(struct task_struct *task, struct seq_file *m, int whole) +static int calc_io_accounting(struct task_struct *task, struct task_io_accounting *acct, int whole) { - struct task_io_accounting acct = task->ioac; unsigned long flags; int result; @@ -2928,12 +2927,27 @@ static int do_io_accounting(struct task_struct *task, struct seq_file *m, int wh if (whole && lock_task_sighand(task, &flags)) { struct task_struct *t = task; - task_io_accounting_add(&acct, &task->signal->ioac); + task_io_accounting_add(acct, &task->signal->ioac); while_each_thread(task, t) - task_io_accounting_add(&acct, &t->ioac); + task_io_accounting_add(acct, &t->ioac); unlock_task_sighand(task, &flags); } + result = 0; + +out_unlock: + mutex_unlock(&task->signal->exec_update_mutex); + return result; +} +static int do_io_accounting(struct task_struct *task, struct seq_file *m, int whole) +{ + struct task_io_accounting acct = task->ioac; + int result; + + result = calc_io_accounting(task, &acct, whole); + if (result) + return result; + seq_printf(m, "rchar: %llu\n" "wchar: %llu\n" @@ -2949,10 +2963,7 @@ static int do_io_accounting(struct task_struct *task, struct seq_file *m, int wh (unsigned long long)acct.read_bytes, (unsigned long long)acct.write_bytes, (unsigned long long)acct.cancelled_write_bytes); - result = 0; -out_unlock: - mutex_unlock(&task->signal->exec_update_mutex); return result; } @@ -3896,7 +3907,42 @@ static int proc_all_statm(struct seq_file *m, void *v) return proc_pid_statm(m, ns, pid, task); } +#ifdef CONFIG_TASK_IO_ACCOUNTING +static int proc_all_io_print_one(struct seq_file *m, struct task_struct *task) +{ + struct task_io_accounting acct = task->ioac; + int result; + result = calc_io_accounting(task, &acct, 1); + if (result) + return result; + + seq_printf(m, + "%llu %llu %llu %llu %llu %llu %llu\n", + (unsigned long long)acct.rchar, + (unsigned long long)acct.wchar, + (unsigned long long)acct.syscr, + (unsigned long long)acct.syscw, + (unsigned long long)acct.read_bytes, + (unsigned long long)acct.write_bytes, + (unsigned long long)acct.cancelled_write_bytes); + + return result; +} + +static int proc_all_io(struct seq_file *m, void *v) +{ + struct all_iter *iter = (struct all_iter *) v; + struct pid_namespace *ns = iter->ns; + struct task_struct *task = iter->tgid_iter.task; + struct pid *pid = task->thread_pid; + + seq_put_decimal_ull(m, "", pid_nr_ns(pid, ns)); + seq_puts(m, " "); + + return proc_all_io_print_one(m, task); +} +#endif static int proc_all_status(struct seq_file *m, void *v) { @@ -3915,6 +3961,9 @@ static int proc_all_status(struct seq_file *m, void *v) PROC_ALL_OPS(stat); PROC_ALL_OPS(statm); PROC_ALL_OPS(status); +#ifdef CONFIG_TASK_IO_ACCOUNTING + PROC_ALL_OPS(io); +#endif #define PROC_ALL_CREATE(NAME) \ do { \ @@ -3932,4 +3981,7 @@ void __init proc_all_init(void) PROC_ALL_CREATE(stat); PROC_ALL_CREATE(statm); PROC_ALL_CREATE(status); +#ifdef CONFIG_TASK_IO_ACCOUNTING + PROC_ALL_CREATE(io); +#endif } -- 2.25.1