select_bad_process: kill a bogus PF_DEAD/TASK_DEAD check
Subsystems (2)
PATCH 1/1 select_bad_process: kill a bogus PF_DEAD/TASK_DEAD check
(Compile tested, on top of introduce-task_dead-state.patch)
The only one usage of TASK_DEAD outside of last schedule path,
select_bad_process:
for_each_task(p) {
if (!p->mm)
continue;
...
if (p->state == TASK_DEAD)
continue;
...TASK_DEAD state is set at the end of do_exit(), this means that p->mm was already set == NULL by exit_mm(), so this task was already rejected by 'if (!p->mm)' above.
Note also that the caller holds tasklist_lock, this means that p can't pass exit_notify() and then set TASK_DEAD when p->mm != NULL.
Also, remove open-coded is_init().
Signed-off-by Oleg Nesterov <[email protected]>
mm/oom_kill.c renamed from mm/oom_kill.c~ +6 -6
@@ -207,11 +207,14 @@ static struct task_struct *select_bad_prunsigned long points;int releasing; -/* skip kernel threads */ +/* +* skip kernel threads and tasks which have already released +* their mm. +*/ if (!p->mm)continue ; -/* skip the init task with pid == 1 */ -if (p->pid ==1 ) +/* skip the init task */ +if (is_init (p))continue ;/*
@@ -227,9 +230,6 @@ static struct task_struct *select_bad_pr releasing =test_tsk_thread_flag (p,TIF_MEMDIE ) || p->flags &PF_EXITING ;if (releasing) { -/* TASK_DEAD tasks have already released their mm */ -if (p->state ==TASK_DEAD ) -continue ;if (p->flags &PF_EXITING && p == current) { chosen = p; *ppoints =ULONG_MAX ;