linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3 1/3] mm, oom: refactor dump_tasks for memcg OOMs
@ 2019-06-24 21:26 Shakeel Butt
  2019-06-24 21:26 ` [PATCH v3 2/3] mm, oom: remove redundant task_in_mem_cgroup() check Shakeel Butt
  2019-06-24 21:26 ` [PATCH v3 3/3] oom: decouple mems_allowed from oom_unkillable_task Shakeel Butt
  0 siblings, 2 replies; 15+ messages in thread
From: Shakeel Butt @ 2019-06-24 21:26 UTC (permalink / raw)
  To: Johannes Weiner, Vladimir Davydov, Michal Hocko, Andrew Morton,
	Roman Gushchin, David Rientjes, KOSAKI Motohiro, Tetsuo Handa,
	Paul Jackson, Nick Piggin
  Cc: linux-mm, linux-kernel, Shakeel Butt, Michal Hocko

dump_tasks() traverses all the existing processes even for the memcg OOM
context which is not only unnecessary but also wasteful. This imposes
a long RCU critical section even from a contained context which can be
quite disruptive.

Change dump_tasks() to be aligned with select_bad_process and use
mem_cgroup_scan_tasks to selectively traverse only processes of the
target memcg hierarchy during memcg OOM.

Signed-off-by: Shakeel Butt <shakeelb@google.com>
Acked-by: Michal Hocko <mhocko@suse.com>

---
Changelog since v2:
- Updated the commit message.

Changelog since v1:
- Divide the patch into two patches.

 mm/oom_kill.c | 68 ++++++++++++++++++++++++++++++---------------------
 1 file changed, 40 insertions(+), 28 deletions(-)

diff --git a/mm/oom_kill.c b/mm/oom_kill.c
index 05aaa1a5920b..bd80997e0969 100644
--- a/mm/oom_kill.c
+++ b/mm/oom_kill.c
@@ -385,10 +385,38 @@ static void select_bad_process(struct oom_control *oc)
 	oc->chosen_points = oc->chosen_points * 1000 / oc->totalpages;
 }
 
+static int dump_task(struct task_struct *p, void *arg)
+{
+	struct oom_control *oc = arg;
+	struct task_struct *task;
+
+	if (oom_unkillable_task(p, NULL, oc->nodemask))
+		return 0;
+
+	task = find_lock_task_mm(p);
+	if (!task) {
+		/*
+		 * This is a kthread or all of p's threads have already
+		 * detached their mm's.  There's no need to report
+		 * them; they can't be oom killed anyway.
+		 */
+		return 0;
+	}
+
+	pr_info("[%7d] %5d %5d %8lu %8lu %8ld %8lu         %5hd %s\n",
+		task->pid, from_kuid(&init_user_ns, task_uid(task)),
+		task->tgid, task->mm->total_vm, get_mm_rss(task->mm),
+		mm_pgtables_bytes(task->mm),
+		get_mm_counter(task->mm, MM_SWAPENTS),
+		task->signal->oom_score_adj, task->comm);
+	task_unlock(task);
+
+	return 0;
+}
+
 /**
  * dump_tasks - dump current memory state of all system tasks
- * @memcg: current's memory controller, if constrained
- * @nodemask: nodemask passed to page allocator for mempolicy ooms
+ * @oc: pointer to struct oom_control
  *
  * Dumps the current memory state of all eligible tasks.  Tasks not in the same
  * memcg, not in the same cpuset, or bound to a disjoint set of mempolicy nodes
@@ -396,37 +424,21 @@ static void select_bad_process(struct oom_control *oc)
  * State information includes task's pid, uid, tgid, vm size, rss,
  * pgtables_bytes, swapents, oom_score_adj value, and name.
  */
-static void dump_tasks(struct mem_cgroup *memcg, const nodemask_t *nodemask)
+static void dump_tasks(struct oom_control *oc)
 {
-	struct task_struct *p;
-	struct task_struct *task;
-
 	pr_info("Tasks state (memory values in pages):\n");
 	pr_info("[  pid  ]   uid  tgid total_vm      rss pgtables_bytes swapents oom_score_adj name\n");
-	rcu_read_lock();
-	for_each_process(p) {
-		if (oom_unkillable_task(p, memcg, nodemask))
-			continue;
 
-		task = find_lock_task_mm(p);
-		if (!task) {
-			/*
-			 * This is a kthread or all of p's threads have already
-			 * detached their mm's.  There's no need to report
-			 * them; they can't be oom killed anyway.
-			 */
-			continue;
-		}
+	if (is_memcg_oom(oc))
+		mem_cgroup_scan_tasks(oc->memcg, dump_task, oc);
+	else {
+		struct task_struct *p;
 
-		pr_info("[%7d] %5d %5d %8lu %8lu %8ld %8lu         %5hd %s\n",
-			task->pid, from_kuid(&init_user_ns, task_uid(task)),
-			task->tgid, task->mm->total_vm, get_mm_rss(task->mm),
-			mm_pgtables_bytes(task->mm),
-			get_mm_counter(task->mm, MM_SWAPENTS),
-			task->signal->oom_score_adj, task->comm);
-		task_unlock(task);
+		rcu_read_lock();
+		for_each_process(p)
+			dump_task(p, oc);
+		rcu_read_unlock();
 	}
-	rcu_read_unlock();
 }
 
 static void dump_oom_summary(struct oom_control *oc, struct task_struct *victim)
@@ -458,7 +470,7 @@ static void dump_header(struct oom_control *oc, struct task_struct *p)
 			dump_unreclaimable_slab();
 	}
 	if (sysctl_oom_dump_tasks)
-		dump_tasks(oc->memcg, oc->nodemask);
+		dump_tasks(oc);
 	if (p)
 		dump_oom_summary(oc, p);
 }
-- 
2.22.0.410.gd8fdbe21b5-goog


^ permalink raw reply related	[flat|nested] 15+ messages in thread
* Re: [PATCH v3 3/3] oom: decouple mems_allowed from oom_unkillable_task
@ 2019-06-26 14:04 Hillf Danton
  0 siblings, 0 replies; 15+ messages in thread
From: Hillf Danton @ 2019-06-26 14:04 UTC (permalink / raw)
  To: Michal Hocko
  Cc: Shakeel Butt, Johannes Weiner, Vladimir Davydov, Andrew Morton,
	Roman Gushchin, David Rientjes, KOSAKI Motohiro, Tetsuo Handa,
	Paul Jackson, linux-mm@kvack.org, linux-kernel@vger.kernel.org,
	syzbot+d0fc9d3c166bc5e4a94b@syzkaller.appspotmail.com


On Wed, 26 Jun 2019 17:18:26 +0800 Michal Hocko wrote:
> On Wed 26-06-19 17:12:10, Hillf Danton wrote:
> >
> > On Mon, 24 Jun 2019 14:27:11 -0700 (PDT) Shakeel Butt wrote:
> > >
> > > @@ -1085,7 +1091,8 @@ bool out_of_memory(struct oom_control *oc)
> > >  	check_panic_on_oom(oc, constraint);
> > > 
> > >  	if (!is_memcg_oom(oc) && sysctl_oom_kill_allocating_task &&
> > > -	    current->mm && !oom_unkillable_task(current, oc->nodemask) &&
> > > +	    current->mm && !oom_unkillable_task(current) &&
> > > +	    has_intersects_mems_allowed(current, oc) &&
> > For what?
> 
> This is explained in the changelog I believe - see the initial section

Correct, Sir.

> about the history and motivation for the check. This patch removes it

I'd read that again.

> from oom_unkillable_task so we have to check it explicitly here.
> 
Thank you very much for the light you are casting, Sir.

--
Hillf
> > >  	    current->signal->oom_score_adj !=3D OOM_SCORE_ADJ_MIN) {
> > >  		get_task_struct(current);
> > >  		oc->chosen =3D current;
> > > --
> > > 2.22.0.410.gd8fdbe21b5-goog
> 
> --
> Michal Hocko
> SUSE Labs


^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2019-06-28  2:17 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2019-06-24 21:26 [PATCH v3 1/3] mm, oom: refactor dump_tasks for memcg OOMs Shakeel Butt
2019-06-24 21:26 ` [PATCH v3 2/3] mm, oom: remove redundant task_in_mem_cgroup() check Shakeel Butt
2019-06-26  6:38   ` Michal Hocko
2019-06-28  2:12     ` Shakeel Butt
2019-06-24 21:26 ` [PATCH v3 3/3] oom: decouple mems_allowed from oom_unkillable_task Shakeel Butt
2019-06-26  6:55   ` Michal Hocko
2019-06-26 10:19     ` Tetsuo Handa
2019-06-26 10:47       ` Michal Hocko
2019-06-26 11:46         ` Tetsuo Handa
2019-06-26 12:15           ` Michal Hocko
2019-06-28  2:17     ` Shakeel Butt
2019-06-26  9:12   ` Hillf Danton
2019-06-26  9:18   ` Michal Hocko
2019-06-26 19:47   ` Roman Gushchin
  -- strict thread matches above, loose matches on Subject: below --
2019-06-26 14:04 Hillf Danton

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).