Commit d49ad935 authored by David Rientjes's avatar David Rientjes Committed by Linus Torvalds

mm, oom: prefer thread group leaders for display purposes

When two threads have the same badness score, it's preferable to kill
the thread group leader so that the actual process name is printed to
the kernel log rather than the thread group name which may be shared
amongst several processes.

This was the behavior when select_bad_process() used to do
for_each_process(), but it now iterates threads instead and leads to
ambiguity.
Signed-off-by: default avatarDavid Rientjes <rientjes@google.com>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Michal Hocko <mhocko@suse.cz>
Cc: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Cc: Greg Thelen <gthelen@google.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent c3ac14b2
...@@ -1841,14 +1841,19 @@ static void mem_cgroup_out_of_memory(struct mem_cgroup *memcg, gfp_t gfp_mask, ...@@ -1841,14 +1841,19 @@ static void mem_cgroup_out_of_memory(struct mem_cgroup *memcg, gfp_t gfp_mask,
break; break;
}; };
points = oom_badness(task, memcg, NULL, totalpages); points = oom_badness(task, memcg, NULL, totalpages);
if (points > chosen_points) { if (!points || points < chosen_points)
continue;
/* Prefer thread group leaders for display purposes */
if (points == chosen_points &&
thread_group_leader(chosen))
continue;
if (chosen) if (chosen)
put_task_struct(chosen); put_task_struct(chosen);
chosen = task; chosen = task;
chosen_points = points; chosen_points = points;
get_task_struct(chosen); get_task_struct(chosen);
} }
}
css_task_iter_end(&it); css_task_iter_end(&it);
} }
......
...@@ -327,11 +327,15 @@ static struct task_struct *select_bad_process(unsigned int *ppoints, ...@@ -327,11 +327,15 @@ static struct task_struct *select_bad_process(unsigned int *ppoints,
break; break;
}; };
points = oom_badness(p, NULL, nodemask, totalpages); points = oom_badness(p, NULL, nodemask, totalpages);
if (points > chosen_points) { if (!points || points < chosen_points)
continue;
/* Prefer thread group leaders for display purposes */
if (points == chosen_points && thread_group_leader(chosen))
continue;
chosen = p; chosen = p;
chosen_points = points; chosen_points = points;
} }
}
if (chosen) if (chosen)
get_task_struct(chosen); get_task_struct(chosen);
rcu_read_unlock(); rcu_read_unlock();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment