Skip to content

Commit

Permalink
task IO accounting: correctly account threads IO statistics
Browse files Browse the repository at this point in the history
Oleg Nesterov points out that we should check that the task is still alive
before we iterate over the threads.  This patch includes a fixup for this.

Also simplify do_io_accounting() implementation.

Signed-off-by: Andrea Righi <righi.andrea@gmail.com>
Signed-off-by: Oleg Nesterov <oleg@tv-sign.ru>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
  • Loading branch information
Andrea Righi authored and Linus Torvalds committed Jul 27, 2008
1 parent 6a9436d commit b2d002d
Showing 1 changed file with 22 additions and 34 deletions.
56 changes: 22 additions & 34 deletions fs/proc/base.c
Original file line number Diff line number Diff line change
Expand Up @@ -2406,35 +2406,18 @@ static int do_io_accounting(struct task_struct *task, char *buffer, int whole)
u64 rchar, wchar, syscr, syscw;
struct task_io_accounting ioac;

if (!whole) {
rchar = task->rchar;
wchar = task->wchar;
syscr = task->syscr;
syscw = task->syscw;
memcpy(&ioac, &task->ioac, sizeof(ioac));
} else {
unsigned long flags;
struct task_struct *t = task;
rchar = wchar = syscr = syscw = 0;
memset(&ioac, 0, sizeof(ioac));
rchar = task->rchar;
wchar = task->wchar;
syscr = task->syscr;
syscw = task->syscw;
memcpy(&ioac, &task->ioac, sizeof(ioac));

rcu_read_lock();
do {
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;
t = next_thread(t);
} while (t != task);
rcu_read_unlock();
if (whole) {
unsigned long flags;

if (lock_task_sighand(task, &flags)) {
struct signal_struct *sig = task->signal;
struct task_struct *t = task;

rchar += sig->rchar;
wchar += sig->wchar;
Expand All @@ -2445,11 +2428,20 @@ static int do_io_accounting(struct task_struct *task, char *buffer, int whole)
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);
}
}

return sprintf(buffer,
"rchar: %llu\n"
"wchar: %llu\n"
Expand All @@ -2458,13 +2450,9 @@ static int do_io_accounting(struct task_struct *task, char *buffer, int whole)
"read_bytes: %llu\n"
"write_bytes: %llu\n"
"cancelled_write_bytes: %llu\n",
(unsigned long long)rchar,
(unsigned long long)wchar,
(unsigned long long)syscr,
(unsigned long long)syscw,
(unsigned long long)ioac.read_bytes,
(unsigned long long)ioac.write_bytes,
(unsigned long long)ioac.cancelled_write_bytes);
rchar, wchar, syscr, syscw,
ioac.read_bytes, ioac.write_bytes,
ioac.cancelled_write_bytes);
}

static int proc_tid_io_accounting(struct task_struct *task, char *buffer)
Expand Down

0 comments on commit b2d002d

Please sign in to comment.