Commit 95751430 authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] fix MCE startup ordering problems

The MCE code is setting up a timer whose handler uses the workqueue code
before workqueue is initialised.  If you boot slowly it oopses.

Convert the MCE code to use an initcall.
parent cffa97e1
...@@ -92,8 +92,4 @@ void __init amd_mcheck_init(struct cpuinfo_x86 *c) ...@@ -92,8 +92,4 @@ void __init amd_mcheck_init(struct cpuinfo_x86 *c)
set_in_cr4 (X86_CR4_MCE); set_in_cr4 (X86_CR4_MCE);
printk (KERN_INFO "Intel machine check reporting enabled on CPU#%d.\n", printk (KERN_INFO "Intel machine check reporting enabled on CPU#%d.\n",
smp_processor_id()); smp_processor_id());
#ifdef CONFIG_X86_MCE_NONFATAL
init_nonfatal_mce_checker();
#endif
} }
...@@ -6,8 +6,6 @@ void intel_p5_mcheck_init(struct cpuinfo_x86 *c); ...@@ -6,8 +6,6 @@ void intel_p5_mcheck_init(struct cpuinfo_x86 *c);
void intel_p6_mcheck_init(struct cpuinfo_x86 *c); void intel_p6_mcheck_init(struct cpuinfo_x86 *c);
void winchip_mcheck_init(struct cpuinfo_x86 *c); void winchip_mcheck_init(struct cpuinfo_x86 *c);
void init_nonfatal_mce_checker(void);
/* Call the installed machine check handler for this CPU setup. */ /* Call the installed machine check handler for this CPU setup. */
extern void (*machine_check_vector)(struct pt_regs *, long error_code); extern void (*machine_check_vector)(struct pt_regs *, long error_code);
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include <linux/workqueue.h> #include <linux/workqueue.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/smp.h> #include <linux/smp.h>
#include <linux/module.h>
#include <asm/processor.h> #include <asm/processor.h>
#include <asm/system.h> #include <asm/system.h>
...@@ -65,7 +66,7 @@ static void mce_timerfunc (unsigned long data) ...@@ -65,7 +66,7 @@ static void mce_timerfunc (unsigned long data)
add_timer (&mce_timer); add_timer (&mce_timer);
} }
void init_nonfatal_mce_checker() static int __init init_nonfatal_mce_checker(void)
{ {
if (timerset == 0) { if (timerset == 0) {
/* Set the timer to check for non-fatal /* Set the timer to check for non-fatal
...@@ -78,4 +79,6 @@ void init_nonfatal_mce_checker() ...@@ -78,4 +79,6 @@ void init_nonfatal_mce_checker()
timerset = 1; timerset = 1;
printk(KERN_INFO "Machine check exception polling timer started.\n"); printk(KERN_INFO "Machine check exception polling timer started.\n");
} }
return 0;
} }
module_init(init_nonfatal_mce_checker);
...@@ -255,7 +255,4 @@ void __init intel_p4_mcheck_init(struct cpuinfo_x86 *c) ...@@ -255,7 +255,4 @@ void __init intel_p4_mcheck_init(struct cpuinfo_x86 *c)
intel_init_thermal(c); intel_init_thermal(c);
#endif #endif
} }
#ifdef CONFIG_X86_MCE_NONFATAL
init_nonfatal_mce_checker();
#endif
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment