diff options
author | KaiGai Kohei <kaigai@ak.jp.nec.com> | 2006-06-25 08:49:26 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-06-25 13:01:25 -0400 |
commit | 77787bfb44da6e6166af088226707aeccee27968 (patch) | |
tree | ada770c2f4f2d913c8f96f2eec3125d4cfb22011 /kernel/acct.c | |
parent | f6ec29a42d7ac3b309a9cef179b686d23986ab98 (diff) |
[PATCH] pacct: none-delayed process accounting accumulation
In current 2.6.17 implementation, signal_struct refered from task_struct is
used for per-process data structure. The pacct facility also uses it as a
per-process data structure to store stime, utime, minflt, majflt. But those
members are saved in __exit_signal(). It's too late.
For example, if some threads exits at same time, pacct facility has a
possibility to drop accountings for a part of those threads. (see, the
following 'The results of original 2.6.17 kernel') I think accounting
information should be completely collected into the per-process data structure
before writing out an accounting record.
This patch fixes this matter. Accumulation of stime, utime, minflt and majflt
are done before generating accounting record.
[mingo@elte.hu: fix acct_collect() siglock bug found by lockdep]
Signed-off-by: KaiGai Kohei <kaigai@ak.jp.nec.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'kernel/acct.c')
-rw-r--r-- | kernel/acct.c | 24 |
1 files changed, 11 insertions, 13 deletions
diff --git a/kernel/acct.c b/kernel/acct.c index 4c85fdf615da..368c4f03fe0e 100644 --- a/kernel/acct.c +++ b/kernel/acct.c | |||
@@ -428,7 +428,6 @@ static void do_acct_process(struct file *file) | |||
428 | u64 elapsed; | 428 | u64 elapsed; |
429 | u64 run_time; | 429 | u64 run_time; |
430 | struct timespec uptime; | 430 | struct timespec uptime; |
431 | unsigned long jiffies; | ||
432 | 431 | ||
433 | /* | 432 | /* |
434 | * First check to see if there is enough free_space to continue | 433 | * First check to see if there is enough free_space to continue |
@@ -469,12 +468,6 @@ static void do_acct_process(struct file *file) | |||
469 | #endif | 468 | #endif |
470 | do_div(elapsed, AHZ); | 469 | do_div(elapsed, AHZ); |
471 | ac.ac_btime = xtime.tv_sec - elapsed; | 470 | ac.ac_btime = xtime.tv_sec - elapsed; |
472 | jiffies = cputime_to_jiffies(cputime_add(current->utime, | ||
473 | current->signal->utime)); | ||
474 | ac.ac_utime = encode_comp_t(jiffies_to_AHZ(jiffies)); | ||
475 | jiffies = cputime_to_jiffies(cputime_add(current->stime, | ||
476 | current->signal->stime)); | ||
477 | ac.ac_stime = encode_comp_t(jiffies_to_AHZ(jiffies)); | ||
478 | /* we really need to bite the bullet and change layout */ | 471 | /* we really need to bite the bullet and change layout */ |
479 | ac.ac_uid = current->uid; | 472 | ac.ac_uid = current->uid; |
480 | ac.ac_gid = current->gid; | 473 | ac.ac_gid = current->gid; |
@@ -497,16 +490,16 @@ static void do_acct_process(struct file *file) | |||
497 | read_unlock(&tasklist_lock); | 490 | read_unlock(&tasklist_lock); |
498 | 491 | ||
499 | spin_lock(¤t->sighand->siglock); | 492 | spin_lock(¤t->sighand->siglock); |
493 | ac.ac_utime = encode_comp_t(jiffies_to_AHZ(cputime_to_jiffies(pacct->ac_utime))); | ||
494 | ac.ac_stime = encode_comp_t(jiffies_to_AHZ(cputime_to_jiffies(pacct->ac_stime))); | ||
500 | ac.ac_flag = pacct->ac_flag; | 495 | ac.ac_flag = pacct->ac_flag; |
501 | ac.ac_mem = encode_comp_t(pacct->ac_mem); | 496 | ac.ac_mem = encode_comp_t(pacct->ac_mem); |
497 | ac.ac_minflt = encode_comp_t(pacct->ac_minflt); | ||
498 | ac.ac_majflt = encode_comp_t(pacct->ac_majflt); | ||
502 | ac.ac_exitcode = pacct->ac_exitcode; | 499 | ac.ac_exitcode = pacct->ac_exitcode; |
503 | spin_unlock(¤t->sighand->siglock); | 500 | spin_unlock(¤t->sighand->siglock); |
504 | ac.ac_io = encode_comp_t(0 /* current->io_usage */); /* %% */ | 501 | ac.ac_io = encode_comp_t(0 /* current->io_usage */); /* %% */ |
505 | ac.ac_rw = encode_comp_t(ac.ac_io / 1024); | 502 | ac.ac_rw = encode_comp_t(ac.ac_io / 1024); |
506 | ac.ac_minflt = encode_comp_t(current->signal->min_flt + | ||
507 | current->min_flt); | ||
508 | ac.ac_majflt = encode_comp_t(current->signal->maj_flt + | ||
509 | current->maj_flt); | ||
510 | ac.ac_swaps = encode_comp_t(0); | 503 | ac.ac_swaps = encode_comp_t(0); |
511 | 504 | ||
512 | /* | 505 | /* |
@@ -532,6 +525,7 @@ static void do_acct_process(struct file *file) | |||
532 | void acct_init_pacct(struct pacct_struct *pacct) | 525 | void acct_init_pacct(struct pacct_struct *pacct) |
533 | { | 526 | { |
534 | memset(pacct, 0, sizeof(struct pacct_struct)); | 527 | memset(pacct, 0, sizeof(struct pacct_struct)); |
528 | pacct->ac_utime = pacct->ac_stime = cputime_zero; | ||
535 | } | 529 | } |
536 | 530 | ||
537 | /** | 531 | /** |
@@ -555,7 +549,7 @@ void acct_collect(long exitcode, int group_dead) | |||
555 | up_read(¤t->mm->mmap_sem); | 549 | up_read(¤t->mm->mmap_sem); |
556 | } | 550 | } |
557 | 551 | ||
558 | spin_lock(¤t->sighand->siglock); | 552 | spin_lock_irq(¤t->sighand->siglock); |
559 | if (group_dead) | 553 | if (group_dead) |
560 | pacct->ac_mem = vsize / 1024; | 554 | pacct->ac_mem = vsize / 1024; |
561 | if (thread_group_leader(current)) { | 555 | if (thread_group_leader(current)) { |
@@ -569,7 +563,11 @@ void acct_collect(long exitcode, int group_dead) | |||
569 | pacct->ac_flag |= ACORE; | 563 | pacct->ac_flag |= ACORE; |
570 | if (current->flags & PF_SIGNALED) | 564 | if (current->flags & PF_SIGNALED) |
571 | pacct->ac_flag |= AXSIG; | 565 | pacct->ac_flag |= AXSIG; |
572 | spin_unlock(¤t->sighand->siglock); | 566 | pacct->ac_utime = cputime_add(pacct->ac_utime, current->utime); |
567 | pacct->ac_stime = cputime_add(pacct->ac_stime, current->stime); | ||
568 | pacct->ac_minflt += current->min_flt; | ||
569 | pacct->ac_majflt += current->maj_flt; | ||
570 | spin_unlock_irq(¤t->sighand->siglock); | ||
573 | } | 571 | } |
574 | 572 | ||
575 | /** | 573 | /** |