diff options
| -rw-r--r-- | arch/x86/kernel/cpu/mcheck/mce.c | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c index c3c66ac6ef74..5be2464cce6a 100644 --- a/arch/x86/kernel/cpu/mcheck/mce.c +++ b/arch/x86/kernel/cpu/mcheck/mce.c | |||
| @@ -189,9 +189,48 @@ void mce_log(struct mce *mce) | |||
| 189 | set_bit(0, &mce_need_notify); | 189 | set_bit(0, &mce_need_notify); |
| 190 | } | 190 | } |
| 191 | 191 | ||
| 192 | static void drain_mcelog_buffer(void) | ||
| 193 | { | ||
| 194 | unsigned int next, i, prev = 0; | ||
| 195 | |||
| 196 | next = rcu_dereference_check_mce(mcelog.next); | ||
| 197 | |||
| 198 | do { | ||
| 199 | struct mce *m; | ||
| 200 | |||
| 201 | /* drain what was logged during boot */ | ||
| 202 | for (i = prev; i < next; i++) { | ||
| 203 | unsigned long start = jiffies; | ||
| 204 | unsigned retries = 1; | ||
| 205 | |||
| 206 | m = &mcelog.entry[i]; | ||
| 207 | |||
| 208 | while (!m->finished) { | ||
| 209 | if (time_after_eq(jiffies, start + 2*retries)) | ||
| 210 | retries++; | ||
| 211 | |||
| 212 | cpu_relax(); | ||
| 213 | |||
| 214 | if (!m->finished && retries >= 4) { | ||
| 215 | pr_err("MCE: skipping error being logged currently!\n"); | ||
| 216 | break; | ||
| 217 | } | ||
| 218 | } | ||
| 219 | smp_rmb(); | ||
| 220 | atomic_notifier_call_chain(&x86_mce_decoder_chain, 0, m); | ||
| 221 | } | ||
| 222 | |||
| 223 | memset(mcelog.entry + prev, 0, (next - prev) * sizeof(*m)); | ||
| 224 | prev = next; | ||
| 225 | next = cmpxchg(&mcelog.next, prev, 0); | ||
| 226 | } while (next != prev); | ||
| 227 | } | ||
| 228 | |||
| 229 | |||
| 192 | void mce_register_decode_chain(struct notifier_block *nb) | 230 | void mce_register_decode_chain(struct notifier_block *nb) |
| 193 | { | 231 | { |
| 194 | atomic_notifier_chain_register(&x86_mce_decoder_chain, nb); | 232 | atomic_notifier_chain_register(&x86_mce_decoder_chain, nb); |
| 233 | drain_mcelog_buffer(); | ||
| 195 | } | 234 | } |
| 196 | EXPORT_SYMBOL_GPL(mce_register_decode_chain); | 235 | EXPORT_SYMBOL_GPL(mce_register_decode_chain); |
| 197 | 236 | ||
