Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1418269 > unrolled thread

[PATCH 10/10] mm, oom: hide mm which is shared with kthread or global init

Started byMichal Hocko <mhocko@kernel.org>
First post2016-06-09 14:00 +0200
Last post2016-06-09 17:50 +0200
Articles 3 — 2 participants

Back to article view | Back to linux.kernel

This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by below is the oldest one visible, not the original post.


Contents

  [PATCH 10/10] mm, oom: hide mm which is shared with kthread or global init Michal Hocko <mhocko@kernel.org> - 2016-06-09 14:00 +0200
    Re: [PATCH 10/10] mm, oom: hide mm which is shared with kthread or global init Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> - 2016-06-09 17:20 +0200
      Re: [PATCH 10/10] mm, oom: hide mm which is shared with kthread or  global init Michal Hocko <mhocko@kernel.org> - 2016-06-09 17:50 +0200

#1418269 — [PATCH 10/10] mm, oom: hide mm which is shared with kthread or global init

FromMichal Hocko <mhocko@kernel.org>
Date2016-06-09 14:00 +0200
Subject[PATCH 10/10] mm, oom: hide mm which is shared with kthread or global init
Message-ID<rI6MW-5RF-33@gated-at.bofh.it>
From: Michal Hocko <mhocko@suse.com>

The only case where the oom_reaper is not triggered for the oom victim
is when it shares the memory with a kernel thread (aka use_mm) or with
the global init. After "mm, oom: skip vforked tasks from being selected"
the victim cannot be a vforked task of the global init so we are left
with clone(CLONE_VM) (without CLONE_SIGHAND). use_mm() users are quite
rare as well.

In order to guarantee a forward progress for the OOM killer make
sure that this really rare cases will not get into the way and hide
the mm from the oom killer by setting MMF_OOM_REAPED flag for it.
oom_scan_process_thread will ignore any TIF_MEMDIE task if it has
MMF_OOM_REAPED flag set to catch these oom victims.

After this patch we should guarantee a forward progress for the OOM
killer even when the selected victim is sharing memory with a kernel
thread or global init.

Changes since v1
- do not exit_oom_victim because oom_scan_process_thread will handle
  those which couldn't terminate in time. exit_oom_victim is not safe
  wrt. oom_disable synchronization.

Signed-off-by: Michal Hocko <mhocko@suse.com>
---
 mm/oom_kill.c | 25 +++++++++++++++++++++----
 1 file changed, 21 insertions(+), 4 deletions(-)

diff --git a/mm/oom_kill.c b/mm/oom_kill.c
index 3e35d2a487cf..6303bc7caeda 100644
--- a/mm/oom_kill.c
+++ b/mm/oom_kill.c
@@ -283,10 +283,22 @@ enum oom_scan_t oom_scan_process_thread(struct oom_control *oc,
 
 	/*
 	 * This task already has access to memory reserves and is being killed.
-	 * Don't allow any other task to have access to the reserves.
+	 * Don't allow any other task to have access to the reserves unless
+	 * the task has MMF_OOM_REAPED because chances that it would release
+	 * any memory is quite low.
 	 */
-	if (!is_sysrq_oom(oc) && atomic_read(&task->signal->oom_victims))
-		return OOM_SCAN_ABORT;
+	if (!is_sysrq_oom(oc) && atomic_read(&task->signal->oom_victims)) {
+		struct task_struct *p = find_lock_task_mm(task);
+		enum oom_scan_t ret = OOM_SCAN_ABORT;
+
+		if (p) {
+			if (test_bit(MMF_OOM_REAPED, &p->mm->flags))
+				ret = OOM_SCAN_CONTINUE;
+			task_unlock(p);
+		}
+
+		return ret;
+	}
 
 	/*
 	 * If task is allocating a lot of memory and has been marked to be
@@ -913,9 +925,14 @@ void oom_kill_process(struct oom_control *oc, struct task_struct *p,
 			/*
 			 * We cannot use oom_reaper for the mm shared by this
 			 * process because it wouldn't get killed and so the
-			 * memory might be still used.
+			 * memory might be still used. Hide the mm from the oom
+			 * killer to guarantee OOM forward progress.
 			 */
 			can_oom_reap = false;
+			set_bit(MMF_OOM_REAPED, &mm->flags);
+			pr_info("oom killer %d (%s) has mm pinned by %d (%s)\n",
+					task_pid_nr(victim), victim->comm,
+					task_pid_nr(p), p->comm);
 			continue;
 		}
 		do_send_sig_info(SIGKILL, SEND_SIG_FORCED, p, true);
-- 
2.8.1

[toc] | [next] | [standalone]


#1418417

FromTetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Date2016-06-09 17:20 +0200
Message-ID<rI9Uu-86C-19@gated-at.bofh.it>
In reply to#1418269
Michal Hocko wrote:
> The only case where the oom_reaper is not triggered for the oom victim
> is when it shares the memory with a kernel thread (aka use_mm) or with
> the global init. After "mm, oom: skip vforked tasks from being selected"
> the victim cannot be a vforked task of the global init so we are left
> with clone(CLONE_VM) (without CLONE_SIGHAND). use_mm() users are quite
> rare as well.

CONFIG_MMU=n is the other case where the oom_reaper is not triggered for
the oom victim.

> 
> In order to guarantee a forward progress for the OOM killer make
> sure that this really rare cases will not get into the way and hide
> the mm from the oom killer by setting MMF_OOM_REAPED flag for it.
> oom_scan_process_thread will ignore any TIF_MEMDIE task if it has
> MMF_OOM_REAPED flag set to catch these oom victims.

Nobody will set MMF_OOM_REAPED flag if can_oom_reap == true on
CONFIG_MMU=n kernel. If a TIF_MEMDIE thread in CONFIG_MMU=n kernel
is blocked before exit_oom_victim() in exit_mm() from do_exit() is
called, the system will lock up. This is not handled in the patch
nor explained in the changelog.

> 
> After this patch we should guarantee a forward progress for the OOM
> killer even when the selected victim is sharing memory with a kernel
> thread or global init.

[toc] | [prev] | [next] | [standalone]


#1418449 — Re: [PATCH 10/10] mm, oom: hide mm which is shared with kthread or global init

FromMichal Hocko <mhocko@kernel.org>
Date2016-06-09 17:50 +0200
SubjectRe: [PATCH 10/10] mm, oom: hide mm which is shared with kthread or global init
Message-ID<rIanw-8jM-19@gated-at.bofh.it>
In reply to#1418417
On Fri 10-06-16 00:15:18, Tetsuo Handa wrote:
[...]
> Nobody will set MMF_OOM_REAPED flag if can_oom_reap == true on
> CONFIG_MMU=n kernel. If a TIF_MEMDIE thread in CONFIG_MMU=n kernel
> is blocked before exit_oom_victim() in exit_mm() from do_exit() is
> called, the system will lock up. This is not handled in the patch
> nor explained in the changelog.

I have made it clear several times that !CONFIG_MMU is not a target
of this patch series nor other OOM changes because I am not convinced
issues which we are trying to solve are real on those platforms. I
am not really sure what you are trying to achieve now with these
!CONFIG_MMU remarks but if you see _real_ regressions for those
configurations please describe them. This generic statements when
CONFIG_MMU implications are put into !CONFIG_MMU context are not really
useful. If there are possible OOM killer deadlocks without this series
then adding these patches shouldn't make them worse.

E.g. this particular patch is basically a noop for !CONFIG_MMU because
use_mm() is MMU specific. It is also highly improbable that a task would
share mm with init...
-- 
Michal Hocko
SUSE Labs

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web