Commit 696e409dbd1ce325129c5030267365619364dfa0
1 parent
41fcb7feed
Exists in
master
and in
7 other branches
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
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 |