x86, MCE: Drain mcelog buffer
authorBorislav Petkov <borislav.petkov@amd.com>
Thu, 8 Dec 2011 11:28:33 +0000 (12:28 +0100)
committerBorislav Petkov <bp@amd64.org>
Wed, 14 Dec 2011 11:50:13 +0000 (12:50 +0100)
Add a function which drains whatever MCEs were logged in already during
boot and before the decoder chains were registered.

Signed-off-by: Borislav Petkov <borislav.petkov@amd.com>
arch/x86/kernel/cpu/mcheck/mce.c

index c3c66ac6ef74e480e4dbe3f883b7ec5a5937537c..5be2464cce6aa499ee30402ca872f67c07edd5a6 100644 (file)
@@ -189,9 +189,48 @@ void mce_log(struct mce *mce)
        set_bit(0, &mce_need_notify);
 }
 
+static void drain_mcelog_buffer(void)
+{
+       unsigned int next, i, prev = 0;
+
+       next = rcu_dereference_check_mce(mcelog.next);
+
+       do {
+               struct mce *m;
+
+               /* drain what was logged during boot */
+               for (i = prev; i < next; i++) {
+                       unsigned long start = jiffies;
+                       unsigned retries = 1;
+
+                       m = &mcelog.entry[i];
+
+                       while (!m->finished) {
+                               if (time_after_eq(jiffies, start + 2*retries))
+                                       retries++;
+
+                               cpu_relax();
+
+                               if (!m->finished && retries >= 4) {
+                                       pr_err("MCE: skipping error being logged currently!\n");
+                                       break;
+                               }
+                       }
+                       smp_rmb();
+                       atomic_notifier_call_chain(&x86_mce_decoder_chain, 0, m);
+               }
+
+               memset(mcelog.entry + prev, 0, (next - prev) * sizeof(*m));
+               prev = next;
+               next = cmpxchg(&mcelog.next, prev, 0);
+       } while (next != prev);
+}
+
+
 void mce_register_decode_chain(struct notifier_block *nb)
 {
        atomic_notifier_chain_register(&x86_mce_decoder_chain, nb);
+       drain_mcelog_buffer();
 }
 EXPORT_SYMBOL_GPL(mce_register_decode_chain);
 
This page took 0.027002 seconds and 5 git commands to generate.