Commit 292c2c8d authored by Ingo Molnar's avatar Ingo Molnar Committed by Linus Torvalds

[PATCH] detached-fix-2.5.34-A0, BK-curr

This fixes three resource accounting related bugs introduced by detached
threads:

 - the 'child CPU usage' fields were updated in wait4 until now - this was
   slightly buggy for a number of reasons, eg. if the exit_code writout
   faults then it's possible to trigger this code multiple times.

 - those threads that do not go through wait4 were not properly accounted.

 - sched_exit() was incorrectly assuming that current == parent. In the
   detached case p->parent is the real parent.

with this patch applied things like 'time' work again for new-style
threaded apps.
parent 97600f56
......@@ -71,19 +71,19 @@ static void release_task(struct task_struct * p)
write_lock_irq(&tasklist_lock);
__exit_sighand(p);
proc_dentry = __unhash_process(p);
p->parent->cutime += p->utime + p->cutime;
p->parent->cstime += p->stime + p->cstime;
p->parent->cmin_flt += p->min_flt + p->cmin_flt;
p->parent->cmaj_flt += p->maj_flt + p->cmaj_flt;
p->parent->cnswap += p->nswap + p->cnswap;
sched_exit(p);
write_unlock_irq(&tasklist_lock);
if (unlikely(proc_dentry != NULL)) {
shrink_dcache_parent(proc_dentry);
dput(proc_dentry);
}
release_thread(p);
if (p != current) {
current->cmin_flt += p->min_flt + p->cmin_flt;
current->cmaj_flt += p->maj_flt + p->cmaj_flt;
current->cnswap += p->nswap + p->cnswap;
sched_exit(p);
}
put_task_struct(p);
}
......@@ -794,8 +794,6 @@ asmlinkage long sys_wait4(pid_t pid,unsigned int * stat_addr, int options, struc
}
goto end_wait4;
case TASK_ZOMBIE:
current->cutime += p->utime + p->cutime;
current->cstime += p->stime + p->cstime;
read_unlock(&tasklist_lock);
retval = ru ? getrusage(p, RUSAGE_BOTH, ru) : 0;
if (!retval && stat_addr) {
......
......@@ -479,17 +479,17 @@ void sched_exit(task_t * p)
{
local_irq_disable();
if (p->first_time_slice) {
current->time_slice += p->time_slice;
if (unlikely(current->time_slice > MAX_TIMESLICE))
current->time_slice = MAX_TIMESLICE;
p->parent->time_slice += p->time_slice;
if (unlikely(p->parent->time_slice > MAX_TIMESLICE))
p->parent->time_slice = MAX_TIMESLICE;
}
local_irq_enable();
/*
* If the child was a (relative-) CPU hog then decrease
* the sleep_avg of the parent as well.
*/
if (p->sleep_avg < current->sleep_avg)
current->sleep_avg = (current->sleep_avg * EXIT_WEIGHT +
if (p->sleep_avg < p->parent->sleep_avg)
p->parent->sleep_avg = (p->parent->sleep_avg * EXIT_WEIGHT +
p->sleep_avg) / (EXIT_WEIGHT + 1);
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment