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 <[email protected]>
---
 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

_______________________________________________
Devel mailing list
[email protected]
https://lists.openvz.org/mailman/listinfo/devel

Reply via email to