diff options
| author | Borislav Petkov <borislav.petkov@amd.com> | 2009-10-07 13:20:38 +0200 | 
|---|---|---|
| committer | Ingo Molnar <mingo@elte.hu> | 2009-10-12 12:24:45 +0200 | 
| commit | fb2531953fd8855abdcf458459020fd382c5deca (patch) | |
| tree | 2967323398aba0369bff02225f0e9d4d00db0c35 /drivers | |
| parent | d93a8f829fe1d2f3002f2c6ddb553d12db420412 (diff) | |
mce, edac: Use an atomic notifier for MCEs decoding
Add an atomic notifier which ensures proper locking when conveying
MCE info to EDAC for decoding. The actual notifier call overrides a
default, negative priority notifier.
Note: make sure we register the default decoder only once since
mcheck_init() runs on each CPU.
Signed-off-by: Borislav Petkov <borislav.petkov@amd.com>
LKML-Reference: <20091003065752.GA8935@liondog.tnic>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/edac/edac_mce_amd.c | 21 | 
1 files changed, 12 insertions, 9 deletions
| diff --git a/drivers/edac/edac_mce_amd.c b/drivers/edac/edac_mce_amd.c index 713ed7d37247..689cc6a6214d 100644 --- a/drivers/edac/edac_mce_amd.c +++ b/drivers/edac/edac_mce_amd.c @@ -3,7 +3,6 @@  static bool report_gart_errors;  static void (*nb_bus_decoder)(int node_id, struct err_regs *regs); -static void (*orig_mce_callback)(struct mce *m);  void amd_report_gart_errors(bool v)  { @@ -363,8 +362,10 @@ static inline void amd_decode_err_code(unsigned int ec)  		pr_warning("Huh? Unknown MCE error 0x%x\n", ec);  } -static void amd_decode_mce(struct mce *m) +static int amd_decode_mce(struct notifier_block *nb, unsigned long val, +			   void *data)  { +	struct mce *m = (struct mce *)data;  	struct err_regs regs;  	int node, ecc; @@ -420,20 +421,22 @@ static void amd_decode_mce(struct mce *m)  	}  	amd_decode_err_code(m->status & 0xffff); + +	return NOTIFY_STOP;  } +static struct notifier_block amd_mce_dec_nb = { +	.notifier_call	= amd_decode_mce, +}; +  static int __init mce_amd_init(void)  {  	/*  	 * We can decode MCEs for Opteron and later CPUs:  	 */  	if ((boot_cpu_data.x86_vendor == X86_VENDOR_AMD) && -	    (boot_cpu_data.x86 >= 0xf)) { -		/* safe the default decode mce callback */ -		orig_mce_callback = x86_mce_decode_callback; - -		x86_mce_decode_callback = amd_decode_mce; -	} +	    (boot_cpu_data.x86 >= 0xf)) +		atomic_notifier_chain_register(&x86_mce_decoder_chain, &amd_mce_dec_nb);  	return 0;  } @@ -442,7 +445,7 @@ early_initcall(mce_amd_init);  #ifdef MODULE  static void __exit mce_amd_exit(void)  { -	x86_mce_decode_callback = orig_mce_callback; +	atomic_notifier_chain_unregister(&x86_mce_decoder_chain, &amd_mce_dec_nb);  }  MODULE_DESCRIPTION("AMD MCE decoder"); | 
