mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Andi Kleen <ak@suse.de>
To: thockin@google.com, patches@x86-64.org, linux-kernel@vger.kernel.org
Subject: [PATCH] [1/30] x86_64: Dynamically adjust machine check interval
Date: Tue,  1 May 2007 05:57:57 +0200 (CEST)	[thread overview]
Message-ID: <20070501035758.00F3113CAF@wotan.suse.de> (raw)
In-Reply-To: <20070501557.815359000@suse.de>


From: Tim Hockin <thockin@google.com>

Background:
 We've found that MCEs (specifically DRAM SBEs) tend to come in bunches,
 especially when we are trying really hard to stress the system out.  The
 current MCE poller uses a static interval which does not care whether it
 has or has not found MCEs recently.

Description:
 This patch makes the MCE poller adjust the polling interval dynamically.
 If we find an MCE, poll 2x faster (down to 10 ms).  When we stop finding
 MCEs, poll 2x slower (up to check_interval seconds).  The check_interval
 tunable becomes the max polling interval.  The "Machine check events
 logged" printk() is rate limited to the check_interval, which should be
 identical behavior to the old functionality.

Result:
 If you start to take a lot of correctable errors (not exceptions), you
 log them faster and more accurately (less chance of overflowing the MCA
 registers).  If you don't take a lot of errors, you will see no change.

Alternatives:
 I considered simply reducing the polling interval to 10 ms immediately
 and keeping it there as long as we continue to find errors.  This felt a
 bit heavy handed, but does perform significantly better for the default
 check_interval of 5 minutes (we're using a few seconds when testing for
 DRAM errors).  I could be convinced to go with this, if anyone felt it
 was not too aggressive.

Testing:
 I used an error-injecting DIMM to create lots of correctable DRAM errors
 and verified that the polling interval accelerates.  The printk() only
 happens once per check_interval seconds.

Patch:
 This patch is against 2.6.21-rc7.

Signed-Off-By: Tim Hockin <thockin@google.com>
Signed-off-by: Andi Kleen <ak@suse.de>

---
 Documentation/x86_64/machinecheck |    7 ++++++-
 arch/x86_64/kernel/mce.c          |   32 ++++++++++++++++++++++++--------
 2 files changed, 30 insertions(+), 9 deletions(-)

Index: linux/Documentation/x86_64/machinecheck
===================================================================
--- linux.orig/Documentation/x86_64/machinecheck
+++ linux/Documentation/x86_64/machinecheck
@@ -36,7 +36,12 @@ between all CPUs.
 
 check_interval
 	How often to poll for corrected machine check errors, in seconds
-	(Note output is hexademical). Default 5 minutes.
+	(Note output is hexademical). Default 5 minutes.  When the poller
+	finds MCEs it triggers an exponential speedup (poll more often) on
+	the polling interval.  When the poller stops finding MCEs, it
+	triggers an exponential backoff (poll less often) on the polling
+	interval. The check_interval variable is both the initial and
+	maximum polling interval.
 
 tolerant
 	Tolerance level. When a machine check exception occurs for a non
Index: linux/arch/x86_64/kernel/mce.c
===================================================================
--- linux.orig/arch/x86_64/kernel/mce.c
+++ linux/arch/x86_64/kernel/mce.c
@@ -323,10 +323,13 @@ void mce_log_therm_throt_event(unsigned 
 #endif /* CONFIG_X86_MCE_INTEL */
 
 /*
- * Periodic polling timer for "silent" machine check errors.
+ * Periodic polling timer for "silent" machine check errors.  If the
+ * poller finds an MCE, poll 2x faster.  When the poller finds no more
+ * errors, poll 2x slower (up to check_interval seconds).
  */
 
 static int check_interval = 5 * 60; /* 5 minutes */
+static int next_interval; /* in jiffies */
 static void mcheck_timer(struct work_struct *work);
 static DECLARE_DELAYED_WORK(mcheck_work, mcheck_timer);
 
@@ -339,7 +342,6 @@ static void mcheck_check_cpu(void *info)
 static void mcheck_timer(struct work_struct *work)
 {
 	on_each_cpu(mcheck_check_cpu, NULL, 1, 1);
-	schedule_delayed_work(&mcheck_work, check_interval * HZ);
 
 	/*
 	 * It's ok to read stale data here for notify_user and
@@ -349,17 +351,30 @@ static void mcheck_timer(struct work_str
 	 * writes.
 	 */
 	if (notify_user && console_logged) {
+		static unsigned long last_print;
+		unsigned long now = jiffies;
+
+		/* if we logged an MCE, reduce the polling interval */
+		next_interval = max(next_interval/2, HZ/100);
 		notify_user = 0;
 		clear_bit(0, &console_logged);
-		printk(KERN_INFO "Machine check events logged\n");
+		if (time_after_eq(now, last_print + (check_interval*HZ))) {
+			last_print = now;
+			printk(KERN_INFO "Machine check events logged\n");
+		}
+	} else {
+		next_interval = min(next_interval*2, check_interval*HZ);
 	}
+
+	schedule_delayed_work(&mcheck_work, next_interval);
 }
 
 
 static __init int periodic_mcheck_init(void)
 { 
-	if (check_interval)
-		schedule_delayed_work(&mcheck_work, check_interval*HZ);
+	next_interval = check_interval * HZ;
+	if (next_interval)
+		schedule_delayed_work(&mcheck_work, next_interval);
 	return 0;
 } 
 __initcall(periodic_mcheck_init);
@@ -597,12 +612,13 @@ static int mce_resume(struct sys_device 
 /* Reinit MCEs after user configuration changes */
 static void mce_restart(void) 
 { 
-	if (check_interval)
+	if (next_interval)
 		cancel_delayed_work(&mcheck_work);
 	/* Timer race is harmless here */
 	on_each_cpu(mce_init, NULL, 1, 1);       
-	if (check_interval)
-		schedule_delayed_work(&mcheck_work, check_interval*HZ);
+	next_interval = check_interval * HZ;
+	if (next_interval)
+		schedule_delayed_work(&mcheck_work, next_interval);
 }
 
 static struct sysdev_class mce_sysclass = {

  reply	other threads:[~2007-05-01  3:58 UTC|newest]

Thread overview: 52+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-05-01  3:57 [PATCH] [0/30] x86 candidate patches for review VII: VDSO, CPUID, NMI watchdog, MCE, misc Andi Kleen
2007-05-01  3:57 ` Andi Kleen [this message]
2007-05-01  3:57 ` [PATCH] [2/30] x86_64: set node_possible_map at runtime - try 2 Andi Kleen
2007-05-01  3:58 ` [PATCH] [3/30] i386: Clean up NMI watchdog code Andi Kleen
2007-05-01  3:58 ` [PATCH] [4/30] x86_64: Use the 32bit wd_ops for 64bit too Andi Kleen
2007-05-01  3:58 ` [PATCH] [5/30] x86_64: Define IGNORE_IOCTL() macro for compat_ioctls Andi Kleen
2007-05-01  3:58 ` [PATCH] [6/30] x86_64: Shut up 32bit emulation for SIOCGIFCOUNT Andi Kleen
2007-05-01  3:58 ` [PATCH] [7/30] x86_64: Avoid overflows during apic timer calibration Andi Kleen
2007-05-01  3:58 ` [PATCH] [8/30] x86_64: Add vDSO for x86-64 with gettimeofday/clock_gettime/getcpu Andi Kleen
2007-05-01  5:57   ` Jeremy Fitzhardinge
2007-05-01  7:23     ` Andi Kleen
2007-05-01  8:00       ` Jeremy Fitzhardinge
2007-05-01  3:58 ` [PATCH] [9/30] x86_64: Use symbolic CPU features in early CPUID check Andi Kleen
2007-05-01  3:58 ` [PATCH] [10/30] x86_64: Drop -traditional for arch/x86_64/boot Andi Kleen
2007-05-01  3:58 ` [PATCH] [11/30] i386: Drop -traditional in arch/i386/boot Andi Kleen
2007-05-01  3:58 ` [PATCH] [12/30] i386: Verify important CPUID bits in real mode Andi Kleen
2007-05-01  3:58 ` [PATCH] [13/30] i386: Evaluate constant cpu features at runtime Andi Kleen
2007-05-01  3:58 ` [PATCH] [14/30] i386: Implement alternative_io for i386 Andi Kleen
2007-05-01  3:58 ` [PATCH] [15/30] i386: Implement X86_FEATURE_SYNC_RDTSC on i386 Andi Kleen
2007-05-01  3:58 ` [PATCH] [16/30] i386: Add X86_FEATURE_RDTSCP Andi Kleen
2007-05-01  3:58 ` [PATCH] [17/30] x86: Use RDTSCP for synchronous get_cycles if possible Andi Kleen
2007-05-01  3:58 ` [PATCH] [18/30] x86_64: Don't enable NUMA for a single node in K8 NUMA scanning Andi Kleen
2007-05-01  3:58 ` [PATCH] [19/30] i386: Little cleanups in smpboot.c Andi Kleen
2007-05-01  3:58 ` [PATCH] [20/30] i386: Remove copy_*_user BUG_ONs for (size < 0) Andi Kleen
2007-05-01  3:58 ` [PATCH] [21/30] x86_64: Print type and size correctly for unknown compat ioctls Andi Kleen
2007-05-01  3:58 ` [PATCH] [22/30] x86_64: Remove CONFIG_REORDER Andi Kleen
2007-05-01  3:58 ` [PATCH] [23/30] x86_64: Share identical video.S between i386 and x86-64 Andi Kleen
2007-05-01  3:58 ` [PATCH] [24/30] x86_64: Shut up warnings for vfat compat ioctls on other file systems Andi Kleen
2007-05-01 15:45   ` Chuck Ebbert
2007-05-02 10:46     ` Andi Kleen
2007-05-01  3:58 ` [PATCH] [25/30] x86_64: Fix allnoconfig error in genapic_flat.c Andi Kleen
2007-05-01  3:58 ` [PATCH] [26/30] i386: Drop noisy e820 debugging printks Andi Kleen
2007-05-01  3:58 ` [PATCH] [27/30] i386: white space fixes in i387.h Andi Kleen
2007-05-01  3:58 ` [PATCH] [28/30] i386: avoid redundant preempt_disable in __unlazy_fpu Andi Kleen
2007-05-01  3:58 ` [PATCH] [29/30] x86_64: Don't exclude asm-offsets.c in Documentation/dontdiff Andi Kleen
2007-05-01  3:58 ` [PATCH] [30/30] x86_64: Add missing !X86_PAE dependincy to the 2G/2G split Andi Kleen
2007-05-01  4:26   ` Eric Dumazet
2007-05-01  6:21     ` Andi Kleen
2007-05-01 13:01       ` Bill Irwin
2007-05-01 13:49         ` Mark Lord
2007-05-01 15:51         ` Eric Dumazet
2007-05-01 17:00           ` Bill Irwin
2007-05-01 17:17             ` Eric W. Biederman
2007-05-01 20:41               ` Eric Dumazet
2007-05-02  9:38             ` Andi Kleen
2007-05-01  4:37   ` William Lee Irwin III
2007-05-01  4:57     ` Eric Dumazet
2007-05-01  5:11       ` William Lee Irwin III
2007-05-01  5:35     ` Eric W. Biederman
2007-05-01 13:32     ` Mark Lord
2007-05-01 14:17       ` William Lee Irwin III
2007-05-01 14:20         ` Mark Lord

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20070501035758.00F3113CAF@wotan.suse.de \
    --to=ak@suse.de \
    --cc=linux-kernel@vger.kernel.org \
    --cc=patches@x86-64.org \
    --cc=thockin@google.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

Powered by JetHome