aboutsummaryrefslogtreecommitdiffstats
path: root/fs/proc/base.c
diff options
context:
space:
mode:
authorAndrea Righi <righi.andrea@gmail.com>2008-07-26 18:22:27 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-07-26 23:16:47 -0400
commitb2d002dba5a8a4c0c3ec96fd1ff3c9def6bd71a1 (patch)
treea87afab3739039531bdec50aa4f588cdd672bd02 /fs/proc/base.c
parent6a9436d0c3cbe8941b1acd5b0736d355295cad98 (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/base.c')
-rw-r--r--fs/proc/base.c56
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
2470static int proc_tid_io_accounting(struct task_struct *task, char *buffer) 2458static int proc_tid_io_accounting(struct task_struct *task, char *buffer)