diff options
author | Oleg Nesterov <oleg@redhat.com> | 2011-06-22 17:09:09 -0400 |
---|---|---|
committer | Oleg Nesterov <oleg@redhat.com> | 2011-06-27 14:30:09 -0400 |
commit | 8677347378044ab564470bced2275520efb3670d (patch) | |
tree | 61baa72f24bb12eadd6956fb0abeb7eabda46b88 /kernel/exit.c | |
parent | 9843a1e977977986d0a4c1000f2229b032572534 (diff) |
make do_notify_parent() __must_check, update the callers
Change other callers of do_notify_parent() to check the value it
returns, this makes the subsequent task_detached() unnecessary.
Mark do_notify_parent() as __must_check.
Use thread_group_leader() instead of !task_detached() to check
if we need to notify the real parent in wait_task_zombie().
Remove the stale comment in release_task(). "just for sanity" is
no longer true, we have to set EXIT_DEAD to avoid the races with
do_wait().
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Acked-by: Tejun Heo <tj@kernel.org>
Diffstat (limited to 'kernel/exit.c')
-rw-r--r-- | kernel/exit.c | 29 |
1 files changed, 8 insertions, 21 deletions
diff --git a/kernel/exit.c b/kernel/exit.c index bb08e938ca74..f68d137ffeb4 100644 --- a/kernel/exit.c +++ b/kernel/exit.c | |||
@@ -190,21 +190,12 @@ repeat: | |||
190 | leader = p->group_leader; | 190 | leader = p->group_leader; |
191 | if (leader != p && thread_group_empty(leader) && leader->exit_state == EXIT_ZOMBIE) { | 191 | if (leader != p && thread_group_empty(leader) && leader->exit_state == EXIT_ZOMBIE) { |
192 | BUG_ON(task_detached(leader)); | 192 | BUG_ON(task_detached(leader)); |
193 | do_notify_parent(leader, leader->exit_signal); | ||
194 | /* | 193 | /* |
195 | * If we were the last child thread and the leader has | 194 | * If we were the last child thread and the leader has |
196 | * exited already, and the leader's parent ignores SIGCHLD, | 195 | * exited already, and the leader's parent ignores SIGCHLD, |
197 | * then we are the one who should release the leader. | 196 | * then we are the one who should release the leader. |
198 | * | ||
199 | * do_notify_parent() will have marked it self-reaping in | ||
200 | * that case. | ||
201 | */ | ||
202 | zap_leader = task_detached(leader); | ||
203 | |||
204 | /* | ||
205 | * This maintains the invariant that release_task() | ||
206 | * only runs on a task in EXIT_DEAD, just for sanity. | ||
207 | */ | 197 | */ |
198 | zap_leader = do_notify_parent(leader, leader->exit_signal); | ||
208 | if (zap_leader) | 199 | if (zap_leader) |
209 | leader->exit_state = EXIT_DEAD; | 200 | leader->exit_state = EXIT_DEAD; |
210 | } | 201 | } |
@@ -766,8 +757,7 @@ static void reparent_leader(struct task_struct *father, struct task_struct *p, | |||
766 | /* If it has exited notify the new parent about this child's death. */ | 757 | /* If it has exited notify the new parent about this child's death. */ |
767 | if (!p->ptrace && | 758 | if (!p->ptrace && |
768 | p->exit_state == EXIT_ZOMBIE && thread_group_empty(p)) { | 759 | p->exit_state == EXIT_ZOMBIE && thread_group_empty(p)) { |
769 | do_notify_parent(p, p->exit_signal); | 760 | if (do_notify_parent(p, p->exit_signal)) { |
770 | if (task_detached(p)) { | ||
771 | p->exit_state = EXIT_DEAD; | 761 | p->exit_state = EXIT_DEAD; |
772 | list_move_tail(&p->sibling, dead); | 762 | list_move_tail(&p->sibling, dead); |
773 | } | 763 | } |
@@ -1351,16 +1341,13 @@ static int wait_task_zombie(struct wait_opts *wo, struct task_struct *p) | |||
1351 | /* We dropped tasklist, ptracer could die and untrace */ | 1341 | /* We dropped tasklist, ptracer could die and untrace */ |
1352 | ptrace_unlink(p); | 1342 | ptrace_unlink(p); |
1353 | /* | 1343 | /* |
1354 | * If this is not a detached task, notify the parent. | 1344 | * If this is not a sub-thread, notify the parent. |
1355 | * If it's still not detached after that, don't release | 1345 | * If parent wants a zombie, don't release it now. |
1356 | * it now. | ||
1357 | */ | 1346 | */ |
1358 | if (!task_detached(p)) { | 1347 | if (thread_group_leader(p) && |
1359 | do_notify_parent(p, p->exit_signal); | 1348 | !do_notify_parent(p, p->exit_signal)) { |
1360 | if (!task_detached(p)) { | 1349 | p->exit_state = EXIT_ZOMBIE; |
1361 | p->exit_state = EXIT_ZOMBIE; | 1350 | p = NULL; |
1362 | p = NULL; | ||
1363 | } | ||
1364 | } | 1351 | } |
1365 | write_unlock_irq(&tasklist_lock); | 1352 | write_unlock_irq(&tasklist_lock); |
1366 | } | 1353 | } |