diff options
author | Rik van Riel <riel@redhat.com> | 2014-08-15 16:05:36 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2014-09-08 02:17:00 -0400 |
commit | 90ed9cbe765ad358b3151a12b8bf889a3cbcd573 (patch) | |
tree | 4c0e144c98d2c4822d1308166eb94de3c70c647f /kernel/exit.c | |
parent | e2627dce268024aff962132057cb8acb219c9c40 (diff) |
exit: Always reap resource stats in __exit_signal()
Oleg pointed out that wait_task_zombie adds a task's usage statistics
to the parent's signal struct, but the task's own signal struct should
also propagate the statistics at exit time.
This allows thread_group_cputime(reaped_zombie) to get the statistics
after __unhash_process() has made the task invisible to for_each_thread,
but before the thread has actually been rcu freed, making sure no
non-monotonic results are returned inside that window.
Suggested-by: Oleg Nesterov <oleg@redhat.com>
Signed-off-by: Rik van Riel <riel@redhat.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: David Rientjes <rientjes@google.com>
Cc: Guillaume Morin <guillaume@morinfr.org>
Cc: Ionut Alexa <ionut.m.alexa@gmail.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Li Zefan <lizefan@huawei.com>
Cc: Michal Hocko <mhocko@suse.cz>
Cc: Michal Schmidt <mschmidt@redhat.com>
Cc: Oleg Nesterov <oleg@redhat.com>
Cc: umgwanakikbuti@gmail.com
Cc: fweisbec@gmail.com
Cc: srao@redhat.com
Cc: lwoodman@redhat.com
Cc: atheurer@redhat.com
Link: http://lkml.kernel.org/r/1408133138-22048-2-git-send-email-riel@redhat.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'kernel/exit.c')
-rw-r--r-- | kernel/exit.c | 43 |
1 files changed, 21 insertions, 22 deletions
diff --git a/kernel/exit.c b/kernel/exit.c index 32c58f7433a3..b93d46dab6fc 100644 --- a/kernel/exit.c +++ b/kernel/exit.c | |||
@@ -115,30 +115,29 @@ static void __exit_signal(struct task_struct *tsk) | |||
115 | 115 | ||
116 | if (tsk == sig->curr_target) | 116 | if (tsk == sig->curr_target) |
117 | sig->curr_target = next_thread(tsk); | 117 | sig->curr_target = next_thread(tsk); |
118 | /* | ||
119 | * Accumulate here the counters for all threads but the | ||
120 | * group leader as they die, so they can be added into | ||
121 | * the process-wide totals when those are taken. | ||
122 | * The group leader stays around as a zombie as long | ||
123 | * as there are other threads. When it gets reaped, | ||
124 | * the exit.c code will add its counts into these totals. | ||
125 | * We won't ever get here for the group leader, since it | ||
126 | * will have been the last reference on the signal_struct. | ||
127 | */ | ||
128 | task_cputime(tsk, &utime, &stime); | ||
129 | sig->utime += utime; | ||
130 | sig->stime += stime; | ||
131 | sig->gtime += task_gtime(tsk); | ||
132 | sig->min_flt += tsk->min_flt; | ||
133 | sig->maj_flt += tsk->maj_flt; | ||
134 | sig->nvcsw += tsk->nvcsw; | ||
135 | sig->nivcsw += tsk->nivcsw; | ||
136 | sig->inblock += task_io_get_inblock(tsk); | ||
137 | sig->oublock += task_io_get_oublock(tsk); | ||
138 | task_io_accounting_add(&sig->ioac, &tsk->ioac); | ||
139 | sig->sum_sched_runtime += tsk->se.sum_exec_runtime; | ||
140 | } | 118 | } |
141 | 119 | ||
120 | /* | ||
121 | * Accumulate here the counters for all threads but the group leader | ||
122 | * as they die, so they can be added into the process-wide totals | ||
123 | * when those are taken. The group leader stays around as a zombie as | ||
124 | * long as there are other threads. When it gets reaped, the exit.c | ||
125 | * code will add its counts into these totals. We won't ever get here | ||
126 | * for the group leader, since it will have been the last reference on | ||
127 | * the signal_struct. | ||
128 | */ | ||
129 | task_cputime(tsk, &utime, &stime); | ||
130 | sig->utime += utime; | ||
131 | sig->stime += stime; | ||
132 | sig->gtime += task_gtime(tsk); | ||
133 | sig->min_flt += tsk->min_flt; | ||
134 | sig->maj_flt += tsk->maj_flt; | ||
135 | sig->nvcsw += tsk->nvcsw; | ||
136 | sig->nivcsw += tsk->nivcsw; | ||
137 | sig->inblock += task_io_get_inblock(tsk); | ||
138 | sig->oublock += task_io_get_oublock(tsk); | ||
139 | task_io_accounting_add(&sig->ioac, &tsk->ioac); | ||
140 | sig->sum_sched_runtime += tsk->se.sum_exec_runtime; | ||
142 | sig->nr_threads--; | 141 | sig->nr_threads--; |
143 | __unhash_process(tsk, group_dead); | 142 | __unhash_process(tsk, group_dead); |
144 | 143 | ||