From b2c3e3287af3a43f87fd6dd578ed88b7a0ae4c51 Mon Sep 17 00:00:00 2001 From: Prakash Gupta Date: Thu, 29 Oct 2020 10:30:23 +0530 Subject: [PATCH] mm/oom_kill: defer panic_on_oom for a timeout It takes sometime for complete memory reclaimed by oom kills to be available, specifically ion allocations. This either require FDs to be closed which is not covered by oom reaper or released by another process not being kiled. So defer panic_on_oom to avoid panic trigger before memory become available. Change-Id: I9f3312c780e4d8444f58de5f781c9c8dfec9b2c7 Signed-off-by: Prakash Gupta --- mm/oom_kill.c | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/mm/oom_kill.c b/mm/oom_kill.c index 1eefd8959121..79bbf39feee2 100644 --- a/mm/oom_kill.c +++ b/mm/oom_kill.c @@ -58,6 +58,9 @@ int sysctl_oom_kill_allocating_task; int sysctl_oom_dump_tasks = 1; int sysctl_reap_mem_on_sigkill = 1; +#ifdef CONFIG_PRIORITIZE_OOM_TASKS +static unsigned long panic_on_oom_timeout; +#endif static int panic_on_adj_zero; module_param(panic_on_adj_zero, int, 0644); @@ -925,6 +928,9 @@ static void __oom_kill_process(struct task_struct *victim, const char *message) * reserves from the user space under its control. */ do_send_sig_info(SIGKILL, SEND_SIG_PRIV, victim, PIDTYPE_TGID); +#ifdef CONFIG_PRIORITIZE_OOM_TASKS + panic_on_oom_timeout = 0; +#endif mark_oom_victim(victim); pr_err("%s: Killed process %d (%s) total-vm:%lukB, anon-rss:%lukB, file-rss:%lukB, shmem-rss:%lukB, UID:%u pgtables:%lukB oom_score_adj:%hd\n", message, task_pid_nr(victim), victim->comm, K(mm->total_vm), @@ -1039,6 +1045,8 @@ static void oom_kill_process(struct oom_control *oc, const char *message) } } +#define PANIC_ON_OOM_DEFER_TIMEOUT (5*HZ) +#define PANIC_ON_OOM_DEFER_WINDOW (20*HZ) /* * Determines whether the kernel must panic because of the panic_on_oom sysctl. */ @@ -1058,6 +1066,20 @@ static void check_panic_on_oom(struct oom_control *oc) /* Do not panic for oom kills triggered by sysrq */ if (is_sysrq_oom(oc)) return; + +#ifdef CONFIG_PRIORITIZE_OOM_TASKS + if (!panic_on_oom_timeout || + time_after_eq(jiffies, panic_on_oom_timeout + + PANIC_ON_OOM_DEFER_WINDOW)) { + panic_on_oom_timeout = jiffies + PANIC_ON_OOM_DEFER_TIMEOUT; + oc->chosen = (void *)-1UL; + return; + } else if (time_before_eq(jiffies, panic_on_oom_timeout)) { + oc->chosen = (void *)-1UL; + return; + } +#endif + dump_header(oc, NULL); panic("Out of memory: %s panic_on_oom is enabled\n", sysctl_panic_on_oom == 2 ? "compulsory" : "system-wide"); @@ -1165,10 +1187,11 @@ bool out_of_memory(struct oom_control *oc) } #endif - if (!oc->chosen) { + if (!oc->chosen) check_panic_on_oom(oc); + + if (!oc->chosen) select_bad_process(oc); - } /* Found nothing?!?! */ if (!oc->chosen) { @@ -1230,6 +1253,9 @@ void add_to_oom_reaper(struct task_struct *p) get_task_struct(p); if (task_will_free_mem(p)) { __mark_oom_victim(p); +#ifdef CONFIG_PRIORITIZE_OOM_TASKS + panic_on_oom_timeout = 0; +#endif wake_oom_reaper(p); } task_unlock(p);