diff options
-rw-r--r-- | kernel/exit.c | 12 |
1 files changed, 9 insertions, 3 deletions
diff --git a/kernel/exit.c b/kernel/exit.c index 1ea4369890a3..6806c55475ee 100644 --- a/kernel/exit.c +++ b/kernel/exit.c | |||
@@ -1287,9 +1287,15 @@ static int wait_task_continued(struct wait_opts *wo, struct task_struct *p) | |||
1287 | static int wait_consider_task(struct wait_opts *wo, int ptrace, | 1287 | static int wait_consider_task(struct wait_opts *wo, int ptrace, |
1288 | struct task_struct *p) | 1288 | struct task_struct *p) |
1289 | { | 1289 | { |
1290 | /* | ||
1291 | * We can race with wait_task_zombie() from another thread. | ||
1292 | * Ensure that EXIT_ZOMBIE -> EXIT_DEAD/EXIT_TRACE transition | ||
1293 | * can't confuse the checks below. | ||
1294 | */ | ||
1295 | int exit_state = ACCESS_ONCE(p->exit_state); | ||
1290 | int ret; | 1296 | int ret; |
1291 | 1297 | ||
1292 | if (unlikely(p->exit_state == EXIT_DEAD)) | 1298 | if (unlikely(exit_state == EXIT_DEAD)) |
1293 | return 0; | 1299 | return 0; |
1294 | 1300 | ||
1295 | ret = eligible_child(wo, p); | 1301 | ret = eligible_child(wo, p); |
@@ -1310,7 +1316,7 @@ static int wait_consider_task(struct wait_opts *wo, int ptrace, | |||
1310 | return 0; | 1316 | return 0; |
1311 | } | 1317 | } |
1312 | 1318 | ||
1313 | if (unlikely(p->exit_state == EXIT_TRACE)) { | 1319 | if (unlikely(exit_state == EXIT_TRACE)) { |
1314 | /* | 1320 | /* |
1315 | * ptrace == 0 means we are the natural parent. In this case | 1321 | * ptrace == 0 means we are the natural parent. In this case |
1316 | * we should clear notask_error, debugger will notify us. | 1322 | * we should clear notask_error, debugger will notify us. |
@@ -1337,7 +1343,7 @@ static int wait_consider_task(struct wait_opts *wo, int ptrace, | |||
1337 | } | 1343 | } |
1338 | 1344 | ||
1339 | /* slay zombie? */ | 1345 | /* slay zombie? */ |
1340 | if (p->exit_state == EXIT_ZOMBIE) { | 1346 | if (exit_state == EXIT_ZOMBIE) { |
1341 | /* we don't reap group leaders with subthreads */ | 1347 | /* we don't reap group leaders with subthreads */ |
1342 | if (!delay_group_leader(p)) { | 1348 | if (!delay_group_leader(p)) { |
1343 | /* | 1349 | /* |