diff mbox series

[5/4] mm, oom: Deduplicate memcg candidates at select_bad_process().

Message ID 84c59c15-fb60-2421-3c75-cf704572f8d3@i-love.sakura.ne.jp (mailing list archive)
State New, archived
Headers show
Series [1/4] mm, oom: Remove redundant OOM score normalization at select_bad_process(). | expand

Commit Message

Tetsuo Handa May 23, 2019, 10:04 p.m. UTC
Since "mm, oom: Avoid potential RCU stall at dump_tasks()." changed to
cache all candidates at select_bad_process(), dump_tasks() started
printing all threads upon memcg OOM event.

Unfortunately, mem_cgroup_scan_tasks() can't traverse on only thread
group leaders because CSS_TASK_ITER_PROCS does not work if the thread
group leader already exit()ed.

Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
---
 mm/oom_kill.c | 17 ++++++++++++++---
 1 file changed, 14 insertions(+), 3 deletions(-)
diff mbox series

Patch

diff --git a/mm/oom_kill.c b/mm/oom_kill.c
index bdd90b53bbd3..a92b2f70d15b 100644
--- a/mm/oom_kill.c
+++ b/mm/oom_kill.c
@@ -334,6 +334,20 @@  static int oom_evaluate_task(struct task_struct *task, void *arg)
 		goto abort;
 	}
 
+	/*
+	 * Since mem_cgroup_scan_tasks() calls this function on each thread
+	 * whlie for_each_process() calls this function on each thread group,
+	 * memcg OOM should evaluate only one thread from each thread group.
+	 */
+	if (is_memcg_oom(oc) && get_nr_threads(task) != 1) {
+		struct task_struct *p;
+
+		list_for_each_entry_reverse(p, &oom_candidate_list,
+					    oom_candidate_list)
+			if (same_thread_group(p, task))
+				goto next;
+	}
+
 	get_task_struct(task);
 	list_add_tail(&task->oom_candidate_list, &oom_candidate_list);
 
@@ -350,9 +364,6 @@  static int oom_evaluate_task(struct task_struct *task, void *arg)
 	if (!points || points < oc->chosen_points)
 		goto next;
 
-	/* Prefer thread group leaders for display purposes */
-	if (points == oc->chosen_points && thread_group_leader(oc->chosen))
-		goto next;
 select:
 	oc->chosen = task;
 	oc->chosen_points = points;