diff --git a/mm/oom_kill.c b/mm/oom_kill.c index b7f119359db9..827ecdf51361 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"); @@ -1169,10 +1191,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) { @@ -1234,6 +1257,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);