1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-12-23 11:18:54 +00:00

Make machine check exception logging more readable. On newer Intel systems,

an uncorrected ECC error tends to fire on all CPUs in a package
simultaneously and the current printf hacks are not sufficient to make
the messages legible.  Instead, use the existing mca_lock spinlock to
serialize calls to mca_log() and change the machine check code to panic
directly when an unrecoverable error is encoutered rather than falling
back to a trap_fatal() call in trap() (which adds nearly a screen-full of
logging messages that aren't useful for machine checks).

MFC after:	2 weeks
This commit is contained in:
John Baldwin 2012-04-02 15:07:22 +00:00
parent 4aed2ce86e
commit f2e3bfc074
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=233781
4 changed files with 10 additions and 13 deletions

View File

@ -233,8 +233,7 @@ trap(struct trapframe *frame)
#endif
if (type == T_MCHK) {
if (!mca_intr())
trap_fatal(frame, 0);
mca_intr();
goto out;
}

View File

@ -254,8 +254,7 @@ trap(struct trapframe *frame)
#endif
if (type == T_MCHK) {
if (!mca_intr())
trap_fatal(frame, 0);
mca_intr();
goto out;
}

View File

@ -48,7 +48,7 @@ struct mca_record {
void cmc_intr(void);
void mca_init(void);
int mca_intr(void);
void mca_intr(void);
void mca_resume(void);
#endif

View File

@ -457,9 +457,9 @@ mca_record_entry(enum scan_mode mode, const struct mca_record *record)
mtx_lock_spin(&mca_lock);
rec = STAILQ_FIRST(&mca_freelist);
if (rec == NULL) {
mtx_unlock_spin(&mca_lock);
printf("MCA: Unable to allocate space for an event.\n");
mca_log(record);
mtx_unlock_spin(&mca_lock);
return;
}
STAILQ_REMOVE_HEAD(&mca_freelist, link);
@ -589,7 +589,9 @@ mca_scan(enum scan_mode mode)
count++;
if (rec.mr_status & ucmask) {
recoverable = 0;
mtx_lock_spin(&mca_lock);
mca_log(&rec);
mtx_unlock_spin(&mca_lock);
}
mca_record_entry(mode, &rec);
}
@ -636,9 +638,7 @@ mca_scan_cpus(void *arg)
STAILQ_FOREACH(mca, &mca_records, link) {
if (!mca->logged) {
mca->logged = 1;
mtx_unlock_spin(&mca_lock);
mca_log(&mca->rec);
mtx_lock_spin(&mca_lock);
}
}
mtx_unlock_spin(&mca_lock);
@ -924,7 +924,7 @@ mca_init_bsp(void *arg __unused)
SYSINIT(mca_init_bsp, SI_SUB_CPU, SI_ORDER_ANY, mca_init_bsp, NULL);
/* Called when a machine check exception fires. */
int
void
mca_intr(void)
{
uint64_t mcg_status;
@ -938,7 +938,7 @@ mca_intr(void)
printf("MC Type: 0x%jx Address: 0x%jx\n",
(uintmax_t)rdmsr(MSR_P5_MC_TYPE),
(uintmax_t)rdmsr(MSR_P5_MC_ADDR));
return (0);
panic("Machine check");
}
/* Scan the banks and check for any non-recoverable errors. */
@ -949,7 +949,8 @@ mca_intr(void)
/* Clear MCIP. */
wrmsr(MSR_MCG_STATUS, mcg_status & ~MCG_STATUS_MCIP);
return (recoverable);
if (!recoverable)
panic("Unrecoverable machine check exception");
}
#ifdef DEV_APIC
@ -972,9 +973,7 @@ cmc_intr(void)
STAILQ_FOREACH(mca, &mca_records, link) {
if (!mca->logged) {
mca->logged = 1;
mtx_unlock_spin(&mca_lock);
mca_log(&mca->rec);
mtx_lock_spin(&mca_lock);
}
}
mtx_unlock_spin(&mca_lock);