aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--kernel/exit.c44
1 files changed, 34 insertions, 10 deletions
diff --git a/kernel/exit.c b/kernel/exit.c
index b4a935c72159..84d13d6bb30b 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -1550,17 +1550,41 @@ static int wait_consider_task(struct wait_opts *wo, int ptrace,
1550 return 0; 1550 return 0;
1551 } 1551 }
1552 1552
1553 /* 1553 /* slay zombie? */
1554 * We don't reap group leaders with subthreads. 1554 if (p->exit_state == EXIT_ZOMBIE) {
1555 */ 1555 /* we don't reap group leaders with subthreads */
1556 if (p->exit_state == EXIT_ZOMBIE && !delay_group_leader(p)) 1556 if (!delay_group_leader(p))
1557 return wait_task_zombie(wo, p); 1557 return wait_task_zombie(wo, p);
1558 1558
1559 /* 1559 /*
1560 * It's stopped or running now, so it might 1560 * Allow access to stopped/continued state via zombie by
1561 * later continue, exit, or stop again. 1561 * falling through. Clearing of notask_error is complex.
1562 */ 1562 *
1563 wo->notask_error = 0; 1563 * When !@ptrace:
1564 *
1565 * If WEXITED is set, notask_error should naturally be
1566 * cleared. If not, subset of WSTOPPED|WCONTINUED is set,
1567 * so, if there are live subthreads, there are events to
1568 * wait for. If all subthreads are dead, it's still safe
1569 * to clear - this function will be called again in finite
1570 * amount time once all the subthreads are released and
1571 * will then return without clearing.
1572 *
1573 * When @ptrace:
1574 *
1575 * Stopped state is per-task and thus can't change once the
1576 * target task dies. Only continued and exited can happen.
1577 * Clear notask_error if WCONTINUED | WEXITED.
1578 */
1579 if (likely(!ptrace) || (wo->wo_flags & (WCONTINUED | WEXITED)))
1580 wo->notask_error = 0;
1581 } else {
1582 /*
1583 * @p is alive and it's gonna stop, continue or exit, so
1584 * there always is something to wait for.
1585 */
1586 wo->notask_error = 0;
1587 }
1564 1588
1565 if (task_stopped_code(p, ptrace)) 1589 if (task_stopped_code(p, ptrace))
1566 return wait_task_stopped(wo, ptrace, p); 1590 return wait_task_stopped(wo, ptrace, p);