[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.
This commit is contained in:
committed by
Linus Torvalds
parent
6bc392741d
commit
0e4648141a
@@ -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
|
||||
|
Reference in New Issue
Block a user