diff mbox series

[2/2] mm, oom: More aggressively ratelimit dump_header().

Message ID 1550325895-9291-2-git-send-email-penguin-kernel@I-love.SAKURA.ne.jp (mailing list archive)
State New, archived
Headers show
Series [1/2] mm, oom: Don't ratelimit OOM summary line. | expand

Commit Message

Tetsuo Handa Feb. 16, 2019, 2:04 p.m. UTC
Since the owner of oom_lock cannot send SIGKILL before dump_header()
completes (which might take minutes if preempted by concurrently allocating
threads) while concurrently allocating threads are expecting that sleeping
for one jiffy is sufficient, we need to make sure that dump_header() is
rarely called so that concurrently allocating threads won't waste CPU time
too much.

This patch makes sure that we waited for at least 5 seconds before calling
dump_header() again. This patch is not helpful for the first call. But
holding off for jiffies spent for previous dump_header() (or at least 5
seconds) should be able to prevent concurrently allocating threads from
wasting CPU time for subsequent dump_header() calls.

Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Cc: yuzhoujian <yuzhoujian@didichuxing.com>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Andrea Arcangeli <aarcange@redhat.com>
Cc: David Rientjes <rientjes@google.com>
Cc: "Kirill A . Shutemov" <kirill.shutemov@linux.intel.com>
Cc: Roman Gushchin <guro@fb.com>
Cc: Yang Shi <yang.s@alibaba-inc.com>
---
 mm/oom_kill.c | 21 +++++++++++++++++----
 1 file changed, 17 insertions(+), 4 deletions(-)
diff mbox series

Patch

diff --git a/mm/oom_kill.c b/mm/oom_kill.c
index 254c7fb..87180b8 100644
--- a/mm/oom_kill.c
+++ b/mm/oom_kill.c
@@ -440,8 +440,17 @@  static void dump_oom_summary(struct oom_control *oc, struct task_struct *victim)
 		from_kuid(&init_user_ns, task_uid(victim)));
 }
 
+static void oom_holdoff_expired(struct timer_list *unused)
+{
+}
+static DEFINE_TIMER(oom_timer, oom_holdoff_expired);
+
 static void dump_header(struct oom_control *oc)
 {
+	unsigned long holdoff = jiffies;
+
+	if (timer_pending(&oom_timer))
+		return;
 	pr_warn("%s invoked oom-killer: gfp_mask=%#x(%pGg), order=%d, oom_score_adj=%hd\n",
 		current->comm, oc->gfp_mask, &oc->gfp_mask, oc->order,
 			current->signal->oom_score_adj);
@@ -458,6 +467,10 @@  static void dump_header(struct oom_control *oc)
 	}
 	if (sysctl_oom_dump_tasks)
 		dump_tasks(oc->memcg, oc->nodemask);
+	holdoff = jiffies - holdoff;
+	if (holdoff < 5 * HZ)
+		holdoff = 5 * HZ;
+	mod_timer(&oom_timer, jiffies + holdoff);
 }
 
 /*
@@ -939,8 +952,6 @@  static void oom_kill_process(struct oom_control *oc, const char *message)
 {
 	struct task_struct *victim = oc->chosen;
 	struct mem_cgroup *oom_group;
-	static DEFINE_RATELIMIT_STATE(oom_rs, DEFAULT_RATELIMIT_INTERVAL,
-					      DEFAULT_RATELIMIT_BURST);
 
 	/*
 	 * If the task is already exiting, don't alarm the sysadmin or kill
@@ -957,8 +968,7 @@  static void oom_kill_process(struct oom_control *oc, const char *message)
 	}
 	task_unlock(victim);
 
-	if (__ratelimit(&oom_rs))
-		dump_header(oc);
+	dump_header(oc);
 	dump_oom_summary(oc, victim);
 
 	/*
@@ -1001,6 +1011,7 @@  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;
+	del_timer_sync(&oom_timer);
 	dump_header(oc);
 	panic("Out of memory: %s panic_on_oom is enabled\n",
 		sysctl_panic_on_oom == 2 ? "compulsory" : "system-wide");
@@ -1085,6 +1096,8 @@  bool out_of_memory(struct oom_control *oc)
 	select_bad_process(oc);
 	/* Found nothing?!?! */
 	if (!oc->chosen) {
+		if (!is_sysrq_oom(oc) && !is_memcg_oom(oc))
+			del_timer_sync(&oom_timer);
 		dump_header(oc);
 		pr_warn("Out of memory and no killable processes...\n");
 		/*