Skip to content

Commit

Permalink
edac_mce: Add an interface driver to report mce errors via edac
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Mauro Carvalho Chehab committed May 10, 2010
1 parent 41fcb7f commit 696e409
Show file tree
Hide file tree
Showing 5 changed files with 107 additions and 1 deletion.
10 changes: 10 additions & 0 deletions arch/x86/kernel/cpu/mcheck/mce.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#include <linux/fs.h>
#include <linux/mm.h>
#include <linux/debugfs.h>
#include <linux/edac_mce.h>

#include <asm/processor.h>
#include <asm/hw_irq.h>
Expand Down Expand Up @@ -168,6 +169,15 @@ void mce_log(struct mce *mce)
for (;;) {
entry = rcu_dereference_check_mce(mcelog.next);
for (;;) {
/*
* If edac_mce is enabled, it will check the error type
* and will process it, if it is a known error.
* Otherwise, the error will be sent through mcelog
* interface
*/
if (edac_mce_parse(mce))
return;

/*
* When the buffer fills up discard new entries.
* Assume that the earlier errors are the more
Expand Down
8 changes: 7 additions & 1 deletion drivers/edac/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,9 @@ config EDAC_MM_EDAC
occurred so that a particular failing memory module can be
replaced. If unsure, select 'Y'.

config EDAC_MCE
tristate

config EDAC_AMD64
tristate "AMD64 (Opteron, Athlon64) K8, F10h, F11h"
depends on EDAC_MM_EDAC && K8_NB && X86_64 && PCI && EDAC_DECODE_MCE
Expand Down Expand Up @@ -169,9 +172,12 @@ config EDAC_I5400
config EDAC_I7CORE
tristate "Intel i7 Core (Nehalem) processors"
depends on EDAC_MM_EDAC && PCI && X86
select EDAC_MCE
help
Support for error detection and correction the Intel
i7 Core (Nehalem) Integrated Memory Controller
i7 Core (Nehalem) Integrated Memory Controller that exists on
newer processors like i7 Core, i7 Core Extreme, Xeon 35xx
and Xeon 55xx processors.

config EDAC_I82860
tristate "Intel 82860"
Expand Down
1 change: 1 addition & 0 deletions drivers/edac/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

obj-$(CONFIG_EDAC) := edac_stub.o
obj-$(CONFIG_EDAC_MM_EDAC) += edac_core.o
obj-$(CONFIG_EDAC_MCE) += edac_mce.o

edac_core-objs := edac_mc.o edac_device.o edac_mc_sysfs.o edac_pci_sysfs.o
edac_core-objs += edac_module.o edac_device_sysfs.o
Expand Down
58 changes: 58 additions & 0 deletions drivers/edac/edac_mce.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/* Provides edac interface to mcelog events
*
* This file may be distributed under the terms of the
* GNU General Public License version 2.
*
* Copyright (c) 2009 by:
* Mauro Carvalho Chehab <mchehab@redhat.com>
*
* Red Hat Inc. http://www.redhat.com
*/

#include <linux/module.h>
#include <linux/edac_mce.h>
#include <asm/mce.h>

int edac_mce_enabled;
EXPORT_SYMBOL_GPL(edac_mce_enabled);


/*
* Extension interface
*/

static LIST_HEAD(edac_mce_list);
static DEFINE_MUTEX(edac_mce_lock);

int edac_mce_register(struct edac_mce *edac_mce)
{
mutex_lock(&edac_mce_lock);
list_add_tail(&edac_mce->list, &edac_mce_list);
mutex_unlock(&edac_mce_lock);
return 0;
}
EXPORT_SYMBOL(edac_mce_register);

void edac_mce_unregister(struct edac_mce *edac_mce)
{
mutex_lock(&edac_mce_lock);
list_del(&edac_mce->list);
mutex_unlock(&edac_mce_lock);
}
EXPORT_SYMBOL(edac_mce_unregister);



int edac_mce_queue(struct mce *mce)
{
struct edac_mce *edac_mce;

list_for_each_entry(edac_mce, &edac_mce_list, list) {
if (edac_mce->check_error(edac_mce->priv, mce))
return 1;
}

/* Nobody queued the error */
return 0;
}
EXPORT_SYMBOL_GPL(edac_mce_queue);
31 changes: 31 additions & 0 deletions include/linux/edac_mce.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/* Provides edac interface to mcelog events
*
* This file may be distributed under the terms of the
* GNU General Public License version 2.
*
* Copyright (c) 2009 by:
* Mauro Carvalho Chehab <mchehab@redhat.com>
*
* Red Hat Inc. http://www.redhat.com
*/

#if defined(CONFIG_EDAC_MCE) || \
(defined(CONFIG_EDAC_MCE_MODULE) && defined(MODULE))

#include <asm/mce.h>
#include <linux/list.h>

struct edac_mce {
struct list_head list;

void *priv;
int (*check_error)(void *priv, struct mce *mce);
};

int edac_mce_register(struct edac_mce *edac_mce);
void edac_mce_unregister(struct edac_mce *edac_mce);
int edac_mce_parse(struct mce *mce);

#else
#define edac_mce_parse(mce) (0)
#endif

0 comments on commit 696e409

Please sign in to comment.