Commit 696e409dbd1ce325129c5030267365619364dfa0

Authored by Mauro Carvalho Chehab
1 parent 41fcb7feed

edac_mce: Add an interface driver to report mce errors via edac

edac_mce module is an interface module that gets mcelog data and
forwards to any registered edac module that expects to receive data via
mce.

Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>

Showing 5 changed files with 107 additions and 1 deletions Side-by-side Diff

arch/x86/kernel/cpu/mcheck/mce.c
... ... @@ -36,6 +36,7 @@
36 36 #include <linux/fs.h>
37 37 #include <linux/mm.h>
38 38 #include <linux/debugfs.h>
  39 +#include <linux/edac_mce.h>
39 40  
40 41 #include <asm/processor.h>
41 42 #include <asm/hw_irq.h>
... ... @@ -168,6 +169,15 @@
168 169 for (;;) {
169 170 entry = rcu_dereference_check_mce(mcelog.next);
170 171 for (;;) {
  172 + /*
  173 + * If edac_mce is enabled, it will check the error type
  174 + * and will process it, if it is a known error.
  175 + * Otherwise, the error will be sent through mcelog
  176 + * interface
  177 + */
  178 + if (edac_mce_parse(mce))
  179 + return;
  180 +
171 181 /*
172 182 * When the buffer fills up discard new entries.
173 183 * Assume that the earlier errors are the more
drivers/edac/Kconfig
... ... @@ -69,6 +69,9 @@
69 69 occurred so that a particular failing memory module can be
70 70 replaced. If unsure, select 'Y'.
71 71  
  72 +config EDAC_MCE
  73 + tristate
  74 +
72 75 config EDAC_AMD64
73 76 tristate "AMD64 (Opteron, Athlon64) K8, F10h, F11h"
74 77 depends on EDAC_MM_EDAC && K8_NB && X86_64 && PCI && EDAC_DECODE_MCE
75 78  
... ... @@ -169,9 +172,12 @@
169 172 config EDAC_I7CORE
170 173 tristate "Intel i7 Core (Nehalem) processors"
171 174 depends on EDAC_MM_EDAC && PCI && X86
  175 + select EDAC_MCE
172 176 help
173 177 Support for error detection and correction the Intel
174   - i7 Core (Nehalem) Integrated Memory Controller
  178 + i7 Core (Nehalem) Integrated Memory Controller that exists on
  179 + newer processors like i7 Core, i7 Core Extreme, Xeon 35xx
  180 + and Xeon 55xx processors.
175 181  
176 182 config EDAC_I82860
177 183 tristate "Intel 82860"
drivers/edac/Makefile
... ... @@ -8,6 +8,7 @@
8 8  
9 9 obj-$(CONFIG_EDAC) := edac_stub.o
10 10 obj-$(CONFIG_EDAC_MM_EDAC) += edac_core.o
  11 +obj-$(CONFIG_EDAC_MCE) += edac_mce.o
11 12  
12 13 edac_core-objs := edac_mc.o edac_device.o edac_mc_sysfs.o edac_pci_sysfs.o
13 14 edac_core-objs += edac_module.o edac_device_sysfs.o
drivers/edac/edac_mce.c
  1 +/* Provides edac interface to mcelog events
  2 + *
  3 + * This file may be distributed under the terms of the
  4 + * GNU General Public License version 2.
  5 + *
  6 + * Copyright (c) 2009 by:
  7 + * Mauro Carvalho Chehab <mchehab@redhat.com>
  8 + *
  9 + * Red Hat Inc. http://www.redhat.com
  10 + */
  11 +
  12 +#include <linux/module.h>
  13 +#include <linux/edac_mce.h>
  14 +#include <asm/mce.h>
  15 +
  16 +int edac_mce_enabled;
  17 +EXPORT_SYMBOL_GPL(edac_mce_enabled);
  18 +
  19 +
  20 +/*
  21 + * Extension interface
  22 + */
  23 +
  24 +static LIST_HEAD(edac_mce_list);
  25 +static DEFINE_MUTEX(edac_mce_lock);
  26 +
  27 +int edac_mce_register(struct edac_mce *edac_mce)
  28 +{
  29 + mutex_lock(&edac_mce_lock);
  30 + list_add_tail(&edac_mce->list, &edac_mce_list);
  31 + mutex_unlock(&edac_mce_lock);
  32 + return 0;
  33 +}
  34 +EXPORT_SYMBOL(edac_mce_register);
  35 +
  36 +void edac_mce_unregister(struct edac_mce *edac_mce)
  37 +{
  38 + mutex_lock(&edac_mce_lock);
  39 + list_del(&edac_mce->list);
  40 + mutex_unlock(&edac_mce_lock);
  41 +}
  42 +EXPORT_SYMBOL(edac_mce_unregister);
  43 +
  44 +
  45 +
  46 +int edac_mce_queue(struct mce *mce)
  47 +{
  48 + struct edac_mce *edac_mce;
  49 +
  50 + list_for_each_entry(edac_mce, &edac_mce_list, list) {
  51 + if (edac_mce->check_error(edac_mce->priv, mce))
  52 + return 1;
  53 + }
  54 +
  55 + /* Nobody queued the error */
  56 + return 0;
  57 +}
  58 +EXPORT_SYMBOL_GPL(edac_mce_queue);
include/linux/edac_mce.h
  1 +/* Provides edac interface to mcelog events
  2 + *
  3 + * This file may be distributed under the terms of the
  4 + * GNU General Public License version 2.
  5 + *
  6 + * Copyright (c) 2009 by:
  7 + * Mauro Carvalho Chehab <mchehab@redhat.com>
  8 + *
  9 + * Red Hat Inc. http://www.redhat.com
  10 + */
  11 +
  12 +#if defined(CONFIG_EDAC_MCE) || \
  13 + (defined(CONFIG_EDAC_MCE_MODULE) && defined(MODULE))
  14 +
  15 +#include <asm/mce.h>
  16 +#include <linux/list.h>
  17 +
  18 +struct edac_mce {
  19 + struct list_head list;
  20 +
  21 + void *priv;
  22 + int (*check_error)(void *priv, struct mce *mce);
  23 +};
  24 +
  25 +int edac_mce_register(struct edac_mce *edac_mce);
  26 +void edac_mce_unregister(struct edac_mce *edac_mce);
  27 +int edac_mce_parse(struct mce *mce);
  28 +
  29 +#else
  30 +#define edac_mce_parse(mce) (0)
  31 +#endif