]> git.ipfire.org Git - people/ms/linux.git/commitdiff
mm, oom: prefer thread group leaders for display purposes
authorDavid Rientjes <rientjes@google.com>
Thu, 23 Jan 2014 23:53:34 +0000 (15:53 -0800)
committerJiri Slaby <jslaby@suse.cz>
Wed, 4 Jun 2014 14:26:19 +0000 (16:26 +0200)
commit d49ad9355420c743c736bfd1dee9eaa5b1a7722a upstream.

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: David 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: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
mm/memcontrol.c
mm/oom_kill.c

index 15429b92ff983fa289d13a64ae632419a341e1ef..213d1b4aafd7d17306faefac91f58511eee4ef7d 100644 (file)
@@ -1820,13 +1820,18 @@ static void mem_cgroup_out_of_memory(struct mem_cgroup *memcg, gfp_t gfp_mask,
                                break;
                        };
                        points = oom_badness(task, memcg, NULL, totalpages);
-                       if (points > chosen_points) {
-                               if (chosen)
-                                       put_task_struct(chosen);
-                               chosen = task;
-                               chosen_points = points;
-                               get_task_struct(chosen);
-                       }
+                       if (!points || points < chosen_points)
+                               continue;
+                       /* Prefer thread group leaders for display purposes */
+                       if (points == chosen_points &&
+                           thread_group_leader(chosen))
+                               continue;
+
+                       if (chosen)
+                               put_task_struct(chosen);
+                       chosen = task;
+                       chosen_points = points;
+                       get_task_struct(chosen);
                }
                css_task_iter_end(&it);
        }
index f5bed7f17463568902360333154e5697acf93e10..a9b5b7ffc4768f9281cb29ed31c9481f4aea4ba1 100644 (file)
@@ -327,10 +327,14 @@ static struct task_struct *select_bad_process(unsigned int *ppoints,
                        break;
                };
                points = oom_badness(p, NULL, nodemask, totalpages);
-               if (points > chosen_points) {
-                       chosen = p;
-                       chosen_points = 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_points = points;
        }
        if (chosen)
                get_task_struct(chosen);