From 0e4648141af02331f21aabcd34940c70f09a2d04 Mon Sep 17 00:00:00 2001 From: KaiGai Kohei Date: Sun, 25 Jun 2006 05:49:24 -0700 Subject: [PATCH] pacct: add pacct_struct to fix some pacct bugs. The pacct facility need an i/o operation when an accounting record is generated. There is a possibility to wake OOM killer up. If OOM killer is activated, it kills some processes to make them release process memory regions. But acct_process() is called in the killed processes context before calling exit_mm(), so those processes cannot release own memory. In the results, any processes stop in this point and it finally cause a system stall. --- kernel/acct.c | 51 ++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 36 insertions(+), 15 deletions(-) (limited to 'kernel/acct.c') diff --git a/kernel/acct.c b/kernel/acct.c index 44dd6bd63517..b35263137824 100644 --- a/kernel/acct.c +++ b/kernel/acct.c @@ -421,9 +421,9 @@ static u32 encode_float(u64 value) */ static void do_acct_process(long exitcode, struct file *file) { + struct pacct_struct *pacct = ¤t->signal->pacct; acct_t ac; mm_segment_t fs; - unsigned long vsize; unsigned long flim; u64 elapsed; u64 run_time; @@ -505,20 +505,9 @@ static void do_acct_process(long exitcode, struct file *file) ac.ac_flag |= ACORE; if (current->flags & PF_SIGNALED) ac.ac_flag |= AXSIG; - - vsize = 0; - if (current->mm) { - struct vm_area_struct *vma; - down_read(¤t->mm->mmap_sem); - vma = current->mm->mmap; - while (vma) { - vsize += vma->vm_end - vma->vm_start; - vma = vma->vm_next; - } - up_read(¤t->mm->mmap_sem); - } - vsize = vsize / 1024; - ac.ac_mem = encode_comp_t(vsize); + spin_lock(¤t->sighand->siglock); + ac.ac_mem = encode_comp_t(pacct->ac_mem); + spin_unlock(¤t->sighand->siglock); ac.ac_io = encode_comp_t(0 /* current->io_usage */); /* %% */ ac.ac_rw = encode_comp_t(ac.ac_io / 1024); ac.ac_minflt = encode_comp_t(current->signal->min_flt + @@ -545,6 +534,38 @@ static void do_acct_process(long exitcode, struct file *file) set_fs(fs); } +/** + * acct_init_pacct - initialize a new pacct_struct + */ +void acct_init_pacct(struct pacct_struct *pacct) +{ + memset(pacct, 0, sizeof(struct pacct_struct)); +} + +/** + * acct_collect - collect accounting information into pacct_struct + */ +void acct_collect(void) +{ + struct pacct_struct *pacct = ¤t->signal->pacct; + unsigned long vsize = 0; + + if (current->mm) { + struct vm_area_struct *vma; + down_read(¤t->mm->mmap_sem); + vma = current->mm->mmap; + while (vma) { + vsize += vma->vm_end - vma->vm_start; + vma = vma->vm_next; + } + up_read(¤t->mm->mmap_sem); + } + + spin_lock(¤t->sighand->siglock); + pacct->ac_mem = vsize / 1024; + spin_unlock(¤t->sighand->siglock); +} + /** * acct_process - now just a wrapper around do_acct_process * @exitcode: task exit code -- cgit v1.2.3-55-g7522