[Devel] [PATCH 10/17] oom: boost dying tasks on global oom

Vladimir Davydov vdavydov at parallels.com
Fri Aug 14 10:03:34 PDT 2015


If an oom victim process has a low prio (nice or via cpu cgroup), it may
take it very long to complete, which is bad, because the system cannot
make progress until it dies. To avoid that, this patch makes oom killer
set victim task prio to the highest possible.

It might be worth submitting this patch upstream. I will probably try.

Signed-off-by: Vladimir Davydov <vdavydov at parallels.com>
---
 mm/oom_kill.c | 17 +++++++++++++++--
 1 file changed, 15 insertions(+), 2 deletions(-)

diff --git a/mm/oom_kill.c b/mm/oom_kill.c
index 0e6f7535a565..ca765a82fa1a 100644
--- a/mm/oom_kill.c
+++ b/mm/oom_kill.c
@@ -294,6 +294,15 @@ enum oom_scan_t oom_scan_process_thread(struct task_struct *task,
 	return OOM_SCAN_OK;
 }
 
+static void boost_dying_task(struct task_struct *p)
+{
+	/*
+	 * Set the dying task scheduling priority to the highest possible so
+	 * that it will die quickly irrespective of its scheduling policy.
+	 */
+	sched_boost_task(p, 0);
+}
+
 /*
  * Simple selection loop. We chose the process with the highest
  * number of 'points'.
@@ -321,6 +330,7 @@ static struct task_struct *select_bad_process(unsigned int *ppoints,
 		case OOM_SCAN_CONTINUE:
 			continue;
 		case OOM_SCAN_ABORT:
+			boost_dying_task(p);
 			rcu_read_unlock();
 			return ERR_PTR(-1UL);
 		case OOM_SCAN_OK:
@@ -426,8 +436,7 @@ void oom_kill_process(struct task_struct *p, gfp_t gfp_mask, int order,
 	 */
 	if (p->flags & PF_EXITING) {
 		set_tsk_thread_flag(p, TIF_MEMDIE);
-		put_task_struct(p);
-		return;
+		goto out;
 	}
 
 	if (__ratelimit(&oom_rs))
@@ -512,6 +521,9 @@ void oom_kill_process(struct task_struct *p, gfp_t gfp_mask, int order,
 	set_tsk_thread_flag(victim, TIF_MEMDIE);
 	do_send_sig_info(SIGKILL, SEND_SIG_FORCED, victim, true);
 	mem_cgroup_note_oom_kill(memcg, victim);
+out:
+	if (!memcg)
+		boost_dying_task(victim);
 	put_task_struct(victim);
 }
 #undef K
@@ -638,6 +650,7 @@ void out_of_memory(struct zonelist *zonelist, gfp_t gfp_mask,
 	 */
 	if (fatal_signal_pending(current) || current->flags & PF_EXITING) {
 		set_thread_flag(TIF_MEMDIE);
+		boost_dying_task(current);
 		return;
 	}
 
-- 
2.1.4




More information about the Devel mailing list