Commit 3aa6ed84 authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] MCE fixes and cleanups

Andi notes that the

	smp_call_function(foo);
	foo();

in there is incorrect on preemptible kernels.

Fix that by using on_each_cpu(), which takes care of such things.

Also, remove the open-coded timer from here.  We have
schedule_delayed_work().

And remove the `timerset' variable, which doesn't do anything.
parent 2d943d44
...@@ -24,8 +24,6 @@ ...@@ -24,8 +24,6 @@
#include "mce.h" #include "mce.h"
static struct timer_list mce_timer;
static int timerset;
static int firstbank; static int firstbank;
#define MCE_RATE 15*HZ /* timer rate is 15s */ #define MCE_RATE 15*HZ /* timer rate is 15s */
...@@ -35,7 +33,6 @@ static void mce_checkregs (void *info) ...@@ -35,7 +33,6 @@ static void mce_checkregs (void *info)
u32 low, high; u32 low, high;
int i; int i;
preempt_disable();
for (i=firstbank; i<nr_mce_banks; i++) { for (i=firstbank; i<nr_mce_banks; i++) {
rdmsr (MSR_IA32_MC0_STATUS+i*4, low, high); rdmsr (MSR_IA32_MC0_STATUS+i*4, low, high);
...@@ -53,25 +50,15 @@ static void mce_checkregs (void *info) ...@@ -53,25 +50,15 @@ static void mce_checkregs (void *info)
wmb(); wmb();
} }
} }
preempt_enable();
} }
static void do_mce_timer(void *data) static void mce_work_fn(void *data);
{ static DECLARE_WORK(mce_work, mce_work_fn, NULL);
smp_call_function (mce_checkregs, NULL, 1, 1);
}
static DECLARE_WORK(mce_work, do_mce_timer, NULL);
static void mce_timerfunc (unsigned long data) static void mce_work_fn(void *data)
{ {
mce_checkregs (NULL); on_each_cpu(mce_checkregs, NULL, 1, 1);
#ifdef CONFIG_SMP schedule_delayed_work(&mce_work, MCE_RATE);
if (num_online_cpus() > 1)
schedule_work (&mce_work);
#endif
mce_timer.expires = jiffies + MCE_RATE;
add_timer (&mce_timer);
} }
static int __init init_nonfatal_mce_checker(void) static int __init init_nonfatal_mce_checker(void)
...@@ -93,17 +80,11 @@ static int __init init_nonfatal_mce_checker(void) ...@@ -93,17 +80,11 @@ static int __init init_nonfatal_mce_checker(void)
else else
firstbank = 0; firstbank = 0;
if (timerset == 0) { /*
/* Set the timer to check for non-fatal * Check for non-fatal errors every MCE_RATE s
errors every MCE_RATE seconds */ */
init_timer (&mce_timer); schedule_delayed_work(&mce_work, MCE_RATE);
mce_timer.expires = jiffies + MCE_RATE;
mce_timer.data = 0;
mce_timer.function = &mce_timerfunc;
add_timer (&mce_timer);
timerset = 1;
printk(KERN_INFO "Machine check exception polling timer started.\n"); printk(KERN_INFO "Machine check exception polling timer started.\n");
}
return 0; return 0;
} }
module_init(init_nonfatal_mce_checker); module_init(init_nonfatal_mce_checker);
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