diff options
author | Peter Zijlstra <a.p.zijlstra@chello.nl> | 2009-02-05 06:24:15 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-02-05 07:04:33 -0500 |
commit | 32bd671d6cbeda60dc73be77fa2b9037d9a9bfa0 (patch) | |
tree | 591c941b9f12ce9f3caefd112f0ada3c5fcc53ab | |
parent | 83895147b702434e6f236deeca75211fd0e3da3a (diff) |
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>
-rw-r--r-- | include/linux/sched.h | 10 | ||||
-rw-r--r-- | kernel/exit.c | 3 | ||||
-rw-r--r-- | kernel/fork.c | 3 | ||||
-rw-r--r-- | kernel/signal.c | 8 |
4 files changed, 18 insertions, 6 deletions
diff --git a/include/linux/sched.h b/include/linux/sched.h index 2127e959e0f4..2e0646a30314 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h | |||
@@ -559,7 +559,7 @@ struct signal_struct { | |||
559 | * Live threads maintain their own counters and add to these | 559 | * Live threads maintain their own counters and add to these |
560 | * in __exit_signal, except for the group leader. | 560 | * in __exit_signal, except for the group leader. |
561 | */ | 561 | */ |
562 | cputime_t cutime, cstime; | 562 | cputime_t utime, stime, cutime, cstime; |
563 | cputime_t gtime; | 563 | cputime_t gtime; |
564 | cputime_t cgtime; | 564 | cputime_t cgtime; |
565 | unsigned long nvcsw, nivcsw, cnvcsw, cnivcsw; | 565 | unsigned long nvcsw, nivcsw, cnvcsw, cnivcsw; |
@@ -568,6 +568,14 @@ struct signal_struct { | |||
568 | struct task_io_accounting ioac; | 568 | struct task_io_accounting ioac; |
569 | 569 | ||
570 | /* | 570 | /* |
571 | * Cumulative ns of schedule CPU time fo dead threads in the | ||
572 | * group, not including a zombie group leader, (This only differs | ||
573 | * from jiffies_to_ns(utime + stime) if sched_clock uses something | ||
574 | * other than jiffies.) | ||
575 | */ | ||
576 | unsigned long long sum_sched_runtime; | ||
577 | |||
578 | /* | ||
571 | * We don't bother to synchronize most readers of this at all, | 579 | * We don't bother to synchronize most readers of this at all, |
572 | * because there is no reader checking a limit that actually needs | 580 | * because there is no reader checking a limit that actually needs |
573 | * to get both rlim_cur and rlim_max atomically, and either one | 581 | * to get both rlim_cur and rlim_max atomically, and either one |
diff --git a/kernel/exit.c b/kernel/exit.c index f80dec3f1875..efd30ccf3858 100644 --- a/kernel/exit.c +++ b/kernel/exit.c | |||
@@ -118,6 +118,8 @@ static void __exit_signal(struct task_struct *tsk) | |||
118 | * We won't ever get here for the group leader, since it | 118 | * We won't ever get here for the group leader, since it |
119 | * will have been the last reference on the signal_struct. | 119 | * will have been the last reference on the signal_struct. |
120 | */ | 120 | */ |
121 | sig->utime = cputime_add(sig->utime, task_utime(tsk)); | ||
122 | sig->stime = cputime_add(sig->stime, task_stime(tsk)); | ||
121 | sig->gtime = cputime_add(sig->gtime, task_gtime(tsk)); | 123 | sig->gtime = cputime_add(sig->gtime, task_gtime(tsk)); |
122 | sig->min_flt += tsk->min_flt; | 124 | sig->min_flt += tsk->min_flt; |
123 | sig->maj_flt += tsk->maj_flt; | 125 | sig->maj_flt += tsk->maj_flt; |
@@ -126,6 +128,7 @@ static void __exit_signal(struct task_struct *tsk) | |||
126 | sig->inblock += task_io_get_inblock(tsk); | 128 | sig->inblock += task_io_get_inblock(tsk); |
127 | sig->oublock += task_io_get_oublock(tsk); | 129 | sig->oublock += task_io_get_oublock(tsk); |
128 | task_io_accounting_add(&sig->ioac, &tsk->ioac); | 130 | task_io_accounting_add(&sig->ioac, &tsk->ioac); |
131 | sig->sum_sched_runtime += tsk->se.sum_exec_runtime; | ||
129 | sig = NULL; /* Marker for below. */ | 132 | sig = NULL; /* Marker for below. */ |
130 | } | 133 | } |
131 | 134 | ||
diff --git a/kernel/fork.c b/kernel/fork.c index 242a706e7721..e8e854a04ad2 100644 --- a/kernel/fork.c +++ b/kernel/fork.c | |||
@@ -851,13 +851,14 @@ static int copy_signal(unsigned long clone_flags, struct task_struct *tsk) | |||
851 | sig->tty_old_pgrp = NULL; | 851 | sig->tty_old_pgrp = NULL; |
852 | sig->tty = NULL; | 852 | sig->tty = NULL; |
853 | 853 | ||
854 | sig->cutime = sig->cstime = cputime_zero; | 854 | sig->utime = sig->stime = sig->cutime = sig->cstime = cputime_zero; |
855 | sig->gtime = cputime_zero; | 855 | sig->gtime = cputime_zero; |
856 | sig->cgtime = cputime_zero; | 856 | sig->cgtime = cputime_zero; |
857 | sig->nvcsw = sig->nivcsw = sig->cnvcsw = sig->cnivcsw = 0; | 857 | sig->nvcsw = sig->nivcsw = sig->cnvcsw = sig->cnivcsw = 0; |
858 | sig->min_flt = sig->maj_flt = sig->cmin_flt = sig->cmaj_flt = 0; | 858 | sig->min_flt = sig->maj_flt = sig->cmin_flt = sig->cmaj_flt = 0; |
859 | sig->inblock = sig->oublock = sig->cinblock = sig->coublock = 0; | 859 | sig->inblock = sig->oublock = sig->cinblock = sig->coublock = 0; |
860 | task_io_accounting_init(&sig->ioac); | 860 | task_io_accounting_init(&sig->ioac); |
861 | sig->sum_sched_runtime = 0; | ||
861 | taskstats_tgid_init(sig); | 862 | taskstats_tgid_init(sig); |
862 | 863 | ||
863 | task_lock(current->group_leader); | 864 | task_lock(current->group_leader); |
diff --git a/kernel/signal.c b/kernel/signal.c index b6b36768b758..2a74fe87c0dd 100644 --- a/kernel/signal.c +++ b/kernel/signal.c | |||
@@ -1367,7 +1367,6 @@ int do_notify_parent(struct task_struct *tsk, int sig) | |||
1367 | struct siginfo info; | 1367 | struct siginfo info; |
1368 | unsigned long flags; | 1368 | unsigned long flags; |
1369 | struct sighand_struct *psig; | 1369 | struct sighand_struct *psig; |
1370 | struct task_cputime cputime; | ||
1371 | int ret = sig; | 1370 | int ret = sig; |
1372 | 1371 | ||
1373 | BUG_ON(sig == -1); | 1372 | BUG_ON(sig == -1); |
@@ -1397,9 +1396,10 @@ int do_notify_parent(struct task_struct *tsk, int sig) | |||
1397 | info.si_uid = __task_cred(tsk)->uid; | 1396 | info.si_uid = __task_cred(tsk)->uid; |
1398 | rcu_read_unlock(); | 1397 | rcu_read_unlock(); |
1399 | 1398 | ||
1400 | thread_group_cputime(tsk, &cputime); | 1399 | info.si_utime = cputime_to_clock_t(cputime_add(tsk->utime, |
1401 | info.si_utime = cputime_to_jiffies(cputime.utime); | 1400 | tsk->signal->utime)); |
1402 | info.si_stime = cputime_to_jiffies(cputime.stime); | 1401 | info.si_stime = cputime_to_clock_t(cputime_add(tsk->stime, |
1402 | tsk->signal->stime)); | ||
1403 | 1403 | ||
1404 | info.si_status = tsk->exit_code & 0x7f; | 1404 | info.si_status = tsk->exit_code & 0x7f; |
1405 | if (tsk->exit_code & 0x80) | 1405 | if (tsk->exit_code & 0x80) |