|
@@ -128,7 +128,6 @@ void mce_setup(struct mce *m)
|
|
|
{
|
|
|
memset(m, 0, sizeof(struct mce));
|
|
|
m->cpu = m->extcpu = smp_processor_id();
|
|
|
- m->tsc = rdtsc();
|
|
|
/* We hope get_seconds stays lockless */
|
|
|
m->time = get_seconds();
|
|
|
m->cpuvendor = boot_cpu_data.x86_vendor;
|
|
@@ -217,9 +216,7 @@ void mce_register_decode_chain(struct notifier_block *nb)
|
|
|
{
|
|
|
atomic_inc(&num_notifiers);
|
|
|
|
|
|
- /* Ensure SRAO notifier has the highest priority in the decode chain. */
|
|
|
- if (nb != &mce_srao_nb && nb->priority == INT_MAX)
|
|
|
- nb->priority -= 1;
|
|
|
+ WARN_ON(nb->priority > MCE_PRIO_LOWEST && nb->priority < MCE_PRIO_EDAC);
|
|
|
|
|
|
atomic_notifier_chain_register(&x86_mce_decoder_chain, nb);
|
|
|
}
|
|
@@ -583,7 +580,7 @@ static int srao_decode_notifier(struct notifier_block *nb, unsigned long val,
|
|
|
}
|
|
|
static struct notifier_block mce_srao_nb = {
|
|
|
.notifier_call = srao_decode_notifier,
|
|
|
- .priority = INT_MAX,
|
|
|
+ .priority = MCE_PRIO_SRAO,
|
|
|
};
|
|
|
|
|
|
static int mce_default_notifier(struct notifier_block *nb, unsigned long val,
|
|
@@ -609,7 +606,7 @@ static int mce_default_notifier(struct notifier_block *nb, unsigned long val,
|
|
|
static struct notifier_block mce_default_nb = {
|
|
|
.notifier_call = mce_default_notifier,
|
|
|
/* lowest prio, we want it to run last. */
|
|
|
- .priority = 0,
|
|
|
+ .priority = MCE_PRIO_LOWEST,
|
|
|
};
|
|
|
|
|
|
/*
|
|
@@ -710,14 +707,8 @@ bool machine_check_poll(enum mcp_flags flags, mce_banks_t *b)
|
|
|
|
|
|
mce_gather_info(&m, NULL);
|
|
|
|
|
|
- /*
|
|
|
- * m.tsc was set in mce_setup(). Clear it if not requested.
|
|
|
- *
|
|
|
- * FIXME: Propagate @flags to mce_gather_info/mce_setup() to avoid
|
|
|
- * that dance.
|
|
|
- */
|
|
|
- if (!(flags & MCP_TIMESTAMP))
|
|
|
- m.tsc = 0;
|
|
|
+ if (flags & MCP_TIMESTAMP)
|
|
|
+ m.tsc = rdtsc();
|
|
|
|
|
|
for (i = 0; i < mca_cfg.banks; i++) {
|
|
|
if (!mce_banks[i].ctl || !test_bit(i, *b))
|
|
@@ -1156,6 +1147,7 @@ void do_machine_check(struct pt_regs *regs, long error_code)
|
|
|
goto out;
|
|
|
|
|
|
mce_gather_info(&m, regs);
|
|
|
+ m.tsc = rdtsc();
|
|
|
|
|
|
final = this_cpu_ptr(&mces_seen);
|
|
|
*final = m;
|
|
@@ -1321,41 +1313,6 @@ int memory_failure(unsigned long pfn, int vector, int flags)
|
|
|
}
|
|
|
#endif
|
|
|
|
|
|
-/*
|
|
|
- * Action optional processing happens here (picking up
|
|
|
- * from the list of faulting pages that do_machine_check()
|
|
|
- * placed into the genpool).
|
|
|
- */
|
|
|
-static void mce_process_work(struct work_struct *dummy)
|
|
|
-{
|
|
|
- mce_gen_pool_process();
|
|
|
-}
|
|
|
-
|
|
|
-#ifdef CONFIG_X86_MCE_INTEL
|
|
|
-/***
|
|
|
- * mce_log_therm_throt_event - Logs the thermal throttling event to mcelog
|
|
|
- * @cpu: The CPU on which the event occurred.
|
|
|
- * @status: Event status information
|
|
|
- *
|
|
|
- * This function should be called by the thermal interrupt after the
|
|
|
- * event has been processed and the decision was made to log the event
|
|
|
- * further.
|
|
|
- *
|
|
|
- * The status parameter will be saved to the 'status' field of 'struct mce'
|
|
|
- * and historically has been the register value of the
|
|
|
- * MSR_IA32_THERMAL_STATUS (Intel) msr.
|
|
|
- */
|
|
|
-void mce_log_therm_throt_event(__u64 status)
|
|
|
-{
|
|
|
- struct mce m;
|
|
|
-
|
|
|
- mce_setup(&m);
|
|
|
- m.bank = MCE_THERMAL_BANK;
|
|
|
- m.status = status;
|
|
|
- mce_log(&m);
|
|
|
-}
|
|
|
-#endif /* CONFIG_X86_MCE_INTEL */
|
|
|
-
|
|
|
/*
|
|
|
* Periodic polling timer for "silent" machine check errors. If the
|
|
|
* poller finds an MCE, poll 2x faster. When the poller finds no more
|
|
@@ -2189,7 +2146,7 @@ int __init mcheck_init(void)
|
|
|
mce_register_decode_chain(&mce_default_nb);
|
|
|
mcheck_vendor_init_severity();
|
|
|
|
|
|
- INIT_WORK(&mce_work, mce_process_work);
|
|
|
+ INIT_WORK(&mce_work, mce_gen_pool_process);
|
|
|
init_irq_work(&mce_irq_work, mce_irq_work_cb);
|
|
|
|
|
|
return 0;
|