diff options
Diffstat (limited to 'mm/oom_kill.c')
-rw-r--r-- | mm/oom_kill.c | 8 |
1 files changed, 8 insertions, 0 deletions
diff --git a/mm/oom_kill.c b/mm/oom_kill.c index cd15e46b8b80..fe0aac2348e5 100644 --- a/mm/oom_kill.c +++ b/mm/oom_kill.c @@ -870,6 +870,13 @@ static void oom_kill_process(struct oom_control *oc, const char *message) * still freeing memory. */ read_lock(&tasklist_lock); + + /* + * The task 'p' might have already exited before reaching here. The + * put_task_struct() will free task_struct 'p' while the loop still try + * to access the field of 'p', so, get an extra reference. + */ + get_task_struct(p); for_each_thread(p, t) { list_for_each_entry(child, &t->children, sibling) { unsigned int child_points; @@ -889,6 +896,7 @@ static void oom_kill_process(struct oom_control *oc, const char *message) } } } + put_task_struct(p); read_unlock(&tasklist_lock); p = find_lock_task_mm(victim); |