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

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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@xxxxxxxxxxxxxxxxxxx>
---
 mm/oom_kill.c | 17 ++++++++++++++---
 1 file changed, 14 insertions(+), 3 deletions(-)

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;
-- 
2.16.5




[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Bugtraq]     [Linux OMAP]     [Linux MIPS]     [eCos]     [Asterisk Internet PBX]     [Linux API]

  Powered by Linux