task IO accounting: improve code readability
Put all i/o statistics in struct proc_io_accounting and use inline functions to
initialize and increment statistics, removing a lot of single variable
assignments.
This also reduces the kernel size as following (with CONFIG_TASK_XACCT=y and
CONFIG_TASK_IO_ACCOUNTING=y).
text data bss dec hex filename
11651 0 0 11651 2d83 kernel/exit.o.before
11619 0 0 11619 2d63 kernel/exit.o.after
10886 132 136 11154 2b92 kernel/fork.o.before
10758 132 136 11026 2b12 kernel/fork.o.after
3082029 807968 4818600 8708597 84e1f5 vmlinux.o.before
3081869 807968 4818600 8708437 84e155 vmlinux.o.after
Signed-off-by: Andrea Righi <righi.andrea@gmail.com>
Acked-by: Oleg Nesterov <oleg@tv-sign.ru>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
diff --git a/fs/proc/base.c b/fs/proc/base.c
index e74308b..3d94906 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -53,6 +53,7 @@
#include <linux/time.h>
#include <linux/proc_fs.h>
#include <linux/stat.h>
+#include <linux/task_io_accounting_ops.h>
#include <linux/init.h>
#include <linux/capability.h>
#include <linux/file.h>
@@ -2402,44 +2403,17 @@
#ifdef CONFIG_TASK_IO_ACCOUNTING
static int do_io_accounting(struct task_struct *task, char *buffer, int whole)
{
- u64 rchar, wchar, syscr, syscw;
- struct task_io_accounting ioac;
+ struct proc_io_accounting acct = task->ioac;
+ unsigned long flags;
- rchar = task->rchar;
- wchar = task->wchar;
- syscr = task->syscr;
- syscw = task->syscw;
- memcpy(&ioac, &task->ioac, sizeof(ioac));
+ if (whole && lock_task_sighand(task, &flags)) {
+ struct task_struct *t = task;
- if (whole) {
- unsigned long flags;
+ task_io_accounting_add(&acct, &task->signal->ioac);
+ while_each_thread(task, t)
+ task_io_accounting_add(&acct, &t->ioac);
- if (lock_task_sighand(task, &flags)) {
- struct signal_struct *sig = task->signal;
- struct task_struct *t = task;
-
- rchar += sig->rchar;
- wchar += sig->wchar;
- syscr += sig->syscr;
- syscw += sig->syscw;
-
- ioac.read_bytes += sig->ioac.read_bytes;
- ioac.write_bytes += sig->ioac.write_bytes;
- ioac.cancelled_write_bytes +=
- sig->ioac.cancelled_write_bytes;
- while_each_thread(task, t) {
- rchar += t->rchar;
- wchar += t->wchar;
- syscr += t->syscr;
- syscw += t->syscw;
-
- ioac.read_bytes += t->ioac.read_bytes;
- ioac.write_bytes += t->ioac.write_bytes;
- ioac.cancelled_write_bytes +=
- t->ioac.cancelled_write_bytes;
- }
- unlock_task_sighand(task, &flags);
- }
+ unlock_task_sighand(task, &flags);
}
return sprintf(buffer,
"rchar: %llu\n"
@@ -2449,9 +2423,10 @@
"read_bytes: %llu\n"
"write_bytes: %llu\n"
"cancelled_write_bytes: %llu\n",
- rchar, wchar, syscr, syscw,
- ioac.read_bytes, ioac.write_bytes,
- ioac.cancelled_write_bytes);
+ acct.chr.rchar, acct.chr.wchar,
+ acct.chr.syscr, acct.chr.syscw,
+ acct.blk.read_bytes, acct.blk.write_bytes,
+ acct.blk.cancelled_write_bytes);
}
static int proc_tid_io_accounting(struct task_struct *task, char *buffer)