diff options
author | Andrea Righi <righi.andrea@gmail.com> | 2008-07-26 18:22:27 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-07-26 23:16:47 -0400 |
commit | b2d002dba5a8a4c0c3ec96fd1ff3c9def6bd71a1 (patch) | |
tree | a87afab3739039531bdec50aa4f588cdd672bd02 /fs/proc | |
parent | 6a9436d0c3cbe8941b1acd5b0736d355295cad98 (diff) |
task IO accounting: correctly account threads IO statistics
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>
Diffstat (limited to 'fs/proc')
-rw-r--r-- | fs/proc/base.c | 56 |
1 files changed, 22 insertions, 34 deletions
diff --git a/fs/proc/base.c b/fs/proc/base.c index 81bce6791bfc..d744aa3c9f74 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c | |||
@@ -2406,35 +2406,18 @@ static int do_io_accounting(struct task_struct *task, char *buffer, int whole) | |||
2406 | u64 rchar, wchar, syscr, syscw; | 2406 | u64 rchar, wchar, syscr, syscw; |
2407 | struct task_io_accounting ioac; | 2407 | struct task_io_accounting ioac; |
2408 | 2408 | ||
2409 | if (!whole) { | 2409 | rchar = task->rchar; |
2410 | rchar = task->rchar; | 2410 | wchar = task->wchar; |
2411 | wchar = task->wchar; | 2411 | syscr = task->syscr; |
2412 | syscr = task->syscr; | 2412 | syscw = task->syscw; |
2413 | syscw = task->syscw; | 2413 | memcpy(&ioac, &task->ioac, sizeof(ioac)); |
2414 | memcpy(&ioac, &task->ioac, sizeof(ioac)); | ||
2415 | } else { | ||
2416 | unsigned long flags; | ||
2417 | struct task_struct *t = task; | ||
2418 | rchar = wchar = syscr = syscw = 0; | ||
2419 | memset(&ioac, 0, sizeof(ioac)); | ||
2420 | 2414 | ||
2421 | rcu_read_lock(); | 2415 | if (whole) { |
2422 | do { | 2416 | unsigned long flags; |
2423 | rchar += t->rchar; | ||
2424 | wchar += t->wchar; | ||
2425 | syscr += t->syscr; | ||
2426 | syscw += t->syscw; | ||
2427 | |||
2428 | ioac.read_bytes += t->ioac.read_bytes; | ||
2429 | ioac.write_bytes += t->ioac.write_bytes; | ||
2430 | ioac.cancelled_write_bytes += | ||
2431 | t->ioac.cancelled_write_bytes; | ||
2432 | t = next_thread(t); | ||
2433 | } while (t != task); | ||
2434 | rcu_read_unlock(); | ||
2435 | 2417 | ||
2436 | if (lock_task_sighand(task, &flags)) { | 2418 | if (lock_task_sighand(task, &flags)) { |
2437 | struct signal_struct *sig = task->signal; | 2419 | struct signal_struct *sig = task->signal; |
2420 | struct task_struct *t = task; | ||
2438 | 2421 | ||
2439 | rchar += sig->rchar; | 2422 | rchar += sig->rchar; |
2440 | wchar += sig->wchar; | 2423 | wchar += sig->wchar; |
@@ -2445,11 +2428,20 @@ static int do_io_accounting(struct task_struct *task, char *buffer, int whole) | |||
2445 | ioac.write_bytes += sig->ioac.write_bytes; | 2428 | ioac.write_bytes += sig->ioac.write_bytes; |
2446 | ioac.cancelled_write_bytes += | 2429 | ioac.cancelled_write_bytes += |
2447 | sig->ioac.cancelled_write_bytes; | 2430 | sig->ioac.cancelled_write_bytes; |
2448 | 2431 | while_each_thread(task, t) { | |
2432 | rchar += t->rchar; | ||
2433 | wchar += t->wchar; | ||
2434 | syscr += t->syscr; | ||
2435 | syscw += t->syscw; | ||
2436 | |||
2437 | ioac.read_bytes += t->ioac.read_bytes; | ||
2438 | ioac.write_bytes += t->ioac.write_bytes; | ||
2439 | ioac.cancelled_write_bytes += | ||
2440 | t->ioac.cancelled_write_bytes; | ||
2441 | } | ||
2449 | unlock_task_sighand(task, &flags); | 2442 | unlock_task_sighand(task, &flags); |
2450 | } | 2443 | } |
2451 | } | 2444 | } |
2452 | |||
2453 | return sprintf(buffer, | 2445 | return sprintf(buffer, |
2454 | "rchar: %llu\n" | 2446 | "rchar: %llu\n" |
2455 | "wchar: %llu\n" | 2447 | "wchar: %llu\n" |
@@ -2458,13 +2450,9 @@ static int do_io_accounting(struct task_struct *task, char *buffer, int whole) | |||
2458 | "read_bytes: %llu\n" | 2450 | "read_bytes: %llu\n" |
2459 | "write_bytes: %llu\n" | 2451 | "write_bytes: %llu\n" |
2460 | "cancelled_write_bytes: %llu\n", | 2452 | "cancelled_write_bytes: %llu\n", |
2461 | (unsigned long long)rchar, | 2453 | rchar, wchar, syscr, syscw, |
2462 | (unsigned long long)wchar, | 2454 | ioac.read_bytes, ioac.write_bytes, |
2463 | (unsigned long long)syscr, | 2455 | ioac.cancelled_write_bytes); |
2464 | (unsigned long long)syscw, | ||
2465 | (unsigned long long)ioac.read_bytes, | ||
2466 | (unsigned long long)ioac.write_bytes, | ||
2467 | (unsigned long long)ioac.cancelled_write_bytes); | ||
2468 | } | 2456 | } |
2469 | 2457 | ||
2470 | static int proc_tid_io_accounting(struct task_struct *task, char *buffer) | 2458 | static int proc_tid_io_accounting(struct task_struct *task, char *buffer) |