signal: re-add dead task accumulation stats.
We're going to split the process wide cpu accounting into two parts:
- clocks; which can take all the time they want since they run
from user context.
- timers; which need constant time tracing but can affort the overhead
because they're default off -- and rare.
The clock readout will go back to a full sum of the thread group, for this
we need to re-add the exit stats that were removed in the initial itimer
rework (f06febc9
: timers: fix itimer/many thread hang).
Furthermore, since that full sum can be rather slow for large thread groups
and we have the complete dead task stats, revert the do_notify_parent time
computation.
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Reviewed-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
This commit is contained in:
parent
83895147b7
commit
32bd671d6c
@ -559,7 +559,7 @@ struct signal_struct {
|
|||||||
* Live threads maintain their own counters and add to these
|
* Live threads maintain their own counters and add to these
|
||||||
* in __exit_signal, except for the group leader.
|
* in __exit_signal, except for the group leader.
|
||||||
*/
|
*/
|
||||||
cputime_t cutime, cstime;
|
cputime_t utime, stime, cutime, cstime;
|
||||||
cputime_t gtime;
|
cputime_t gtime;
|
||||||
cputime_t cgtime;
|
cputime_t cgtime;
|
||||||
unsigned long nvcsw, nivcsw, cnvcsw, cnivcsw;
|
unsigned long nvcsw, nivcsw, cnvcsw, cnivcsw;
|
||||||
@ -567,6 +567,14 @@ struct signal_struct {
|
|||||||
unsigned long inblock, oublock, cinblock, coublock;
|
unsigned long inblock, oublock, cinblock, coublock;
|
||||||
struct task_io_accounting ioac;
|
struct task_io_accounting ioac;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Cumulative ns of schedule CPU time fo dead threads in the
|
||||||
|
* group, not including a zombie group leader, (This only differs
|
||||||
|
* from jiffies_to_ns(utime + stime) if sched_clock uses something
|
||||||
|
* other than jiffies.)
|
||||||
|
*/
|
||||||
|
unsigned long long sum_sched_runtime;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We don't bother to synchronize most readers of this at all,
|
* We don't bother to synchronize most readers of this at all,
|
||||||
* because there is no reader checking a limit that actually needs
|
* because there is no reader checking a limit that actually needs
|
||||||
|
@ -118,6 +118,8 @@ static void __exit_signal(struct task_struct *tsk)
|
|||||||
* We won't ever get here for the group leader, since it
|
* We won't ever get here for the group leader, since it
|
||||||
* will have been the last reference on the signal_struct.
|
* will have been the last reference on the signal_struct.
|
||||||
*/
|
*/
|
||||||
|
sig->utime = cputime_add(sig->utime, task_utime(tsk));
|
||||||
|
sig->stime = cputime_add(sig->stime, task_stime(tsk));
|
||||||
sig->gtime = cputime_add(sig->gtime, task_gtime(tsk));
|
sig->gtime = cputime_add(sig->gtime, task_gtime(tsk));
|
||||||
sig->min_flt += tsk->min_flt;
|
sig->min_flt += tsk->min_flt;
|
||||||
sig->maj_flt += tsk->maj_flt;
|
sig->maj_flt += tsk->maj_flt;
|
||||||
@ -126,6 +128,7 @@ static void __exit_signal(struct task_struct *tsk)
|
|||||||
sig->inblock += task_io_get_inblock(tsk);
|
sig->inblock += task_io_get_inblock(tsk);
|
||||||
sig->oublock += task_io_get_oublock(tsk);
|
sig->oublock += task_io_get_oublock(tsk);
|
||||||
task_io_accounting_add(&sig->ioac, &tsk->ioac);
|
task_io_accounting_add(&sig->ioac, &tsk->ioac);
|
||||||
|
sig->sum_sched_runtime += tsk->se.sum_exec_runtime;
|
||||||
sig = NULL; /* Marker for below. */
|
sig = NULL; /* Marker for below. */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -851,13 +851,14 @@ static int copy_signal(unsigned long clone_flags, struct task_struct *tsk)
|
|||||||
sig->tty_old_pgrp = NULL;
|
sig->tty_old_pgrp = NULL;
|
||||||
sig->tty = NULL;
|
sig->tty = NULL;
|
||||||
|
|
||||||
sig->cutime = sig->cstime = cputime_zero;
|
sig->utime = sig->stime = sig->cutime = sig->cstime = cputime_zero;
|
||||||
sig->gtime = cputime_zero;
|
sig->gtime = cputime_zero;
|
||||||
sig->cgtime = cputime_zero;
|
sig->cgtime = cputime_zero;
|
||||||
sig->nvcsw = sig->nivcsw = sig->cnvcsw = sig->cnivcsw = 0;
|
sig->nvcsw = sig->nivcsw = sig->cnvcsw = sig->cnivcsw = 0;
|
||||||
sig->min_flt = sig->maj_flt = sig->cmin_flt = sig->cmaj_flt = 0;
|
sig->min_flt = sig->maj_flt = sig->cmin_flt = sig->cmaj_flt = 0;
|
||||||
sig->inblock = sig->oublock = sig->cinblock = sig->coublock = 0;
|
sig->inblock = sig->oublock = sig->cinblock = sig->coublock = 0;
|
||||||
task_io_accounting_init(&sig->ioac);
|
task_io_accounting_init(&sig->ioac);
|
||||||
|
sig->sum_sched_runtime = 0;
|
||||||
taskstats_tgid_init(sig);
|
taskstats_tgid_init(sig);
|
||||||
|
|
||||||
task_lock(current->group_leader);
|
task_lock(current->group_leader);
|
||||||
|
@ -1367,7 +1367,6 @@ int do_notify_parent(struct task_struct *tsk, int sig)
|
|||||||
struct siginfo info;
|
struct siginfo info;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
struct sighand_struct *psig;
|
struct sighand_struct *psig;
|
||||||
struct task_cputime cputime;
|
|
||||||
int ret = sig;
|
int ret = sig;
|
||||||
|
|
||||||
BUG_ON(sig == -1);
|
BUG_ON(sig == -1);
|
||||||
@ -1397,9 +1396,10 @@ int do_notify_parent(struct task_struct *tsk, int sig)
|
|||||||
info.si_uid = __task_cred(tsk)->uid;
|
info.si_uid = __task_cred(tsk)->uid;
|
||||||
rcu_read_unlock();
|
rcu_read_unlock();
|
||||||
|
|
||||||
thread_group_cputime(tsk, &cputime);
|
info.si_utime = cputime_to_clock_t(cputime_add(tsk->utime,
|
||||||
info.si_utime = cputime_to_jiffies(cputime.utime);
|
tsk->signal->utime));
|
||||||
info.si_stime = cputime_to_jiffies(cputime.stime);
|
info.si_stime = cputime_to_clock_t(cputime_add(tsk->stime,
|
||||||
|
tsk->signal->stime));
|
||||||
|
|
||||||
info.si_status = tsk->exit_code & 0x7f;
|
info.si_status = tsk->exit_code & 0x7f;
|
||||||
if (tsk->exit_code & 0x80)
|
if (tsk->exit_code & 0x80)
|
||||||
|
Loading…
Reference in New Issue
Block a user