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.




 arch/i386/kernel/cpu/mcheck/k7.c        |    4 ----
 arch/i386/kernel/cpu/mcheck/mce.h       |    2 --
 arch/i386/kernel/cpu/mcheck/non-fatal.c |    5 ++++-
 arch/i386/kernel/cpu/mcheck/p4.c        |    3 ---
 4 files changed, 4 insertions(+), 10 deletions(-)

diff -puN arch/i386/kernel/cpu/mcheck/k7.c~mce-workqueue-startup-fix arch/i386/kernel/cpu/mcheck/k7.c
--- 25/arch/i386/kernel/cpu/mcheck/k7.c~mce-workqueue-startup-fix	2003-04-13 16:54:48.000000000 -0700
+++ 25-akpm/arch/i386/kernel/cpu/mcheck/k7.c	2003-04-13 16:54:48.000000000 -0700
@@ -92,8 +92,4 @@ void __init amd_mcheck_init(struct cpuin
 	set_in_cr4 (X86_CR4_MCE);
 	printk (KERN_INFO "Intel machine check reporting enabled on CPU#%d.\n",
 		smp_processor_id());
-
-#ifdef CONFIG_X86_MCE_NONFATAL
-	init_nonfatal_mce_checker();
-#endif
 }
diff -puN arch/i386/kernel/cpu/mcheck/mce.h~mce-workqueue-startup-fix arch/i386/kernel/cpu/mcheck/mce.h
--- 25/arch/i386/kernel/cpu/mcheck/mce.h~mce-workqueue-startup-fix	2003-04-13 16:54:48.000000000 -0700
+++ 25-akpm/arch/i386/kernel/cpu/mcheck/mce.h	2003-04-13 16:54:48.000000000 -0700
@@ -6,8 +6,6 @@ void intel_p5_mcheck_init(struct cpuinfo
 void intel_p6_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. */
 extern void (*machine_check_vector)(struct pt_regs *, long error_code);
 
diff -puN arch/i386/kernel/cpu/mcheck/non-fatal.c~mce-workqueue-startup-fix arch/i386/kernel/cpu/mcheck/non-fatal.c
--- 25/arch/i386/kernel/cpu/mcheck/non-fatal.c~mce-workqueue-startup-fix	2003-04-13 16:54:48.000000000 -0700
+++ 25-akpm/arch/i386/kernel/cpu/mcheck/non-fatal.c	2003-04-13 16:54:48.000000000 -0700
@@ -11,6 +11,7 @@
 #include <linux/workqueue.h>
 #include <linux/interrupt.h>
 #include <linux/smp.h>
+#include <linux/module.h>
 
 #include <asm/processor.h> 
 #include <asm/system.h>
@@ -65,7 +66,7 @@ static void mce_timerfunc (unsigned long
 	add_timer (&mce_timer);
 }	
 
-void init_nonfatal_mce_checker()
+static int init_nonfatal_mce_checker()
 {
 	if (timerset == 0) {
 		/* Set the timer to check for non-fatal
@@ -78,4 +79,6 @@ void init_nonfatal_mce_checker()
 		timerset = 1;
 		printk(KERN_INFO "Machine check exception polling timer started.\n");
 	}
+	return 0;
 }
+module_init(init_nonfatal_mce_checker);
diff -puN arch/i386/kernel/cpu/mcheck/p4.c~mce-workqueue-startup-fix arch/i386/kernel/cpu/mcheck/p4.c
--- 25/arch/i386/kernel/cpu/mcheck/p4.c~mce-workqueue-startup-fix	2003-04-13 16:54:48.000000000 -0700
+++ 25-akpm/arch/i386/kernel/cpu/mcheck/p4.c	2003-04-13 16:54:48.000000000 -0700
@@ -255,7 +255,4 @@ void __init intel_p4_mcheck_init(struct 
 		intel_init_thermal(c);
 #endif
 	}
-#ifdef CONFIG_X86_MCE_NONFATAL
-	init_nonfatal_mce_checker();
-#endif
 }

_