Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 1 Apr 2018 16:42:13 +0000 (UTC)
From:      Mark Johnston <markj@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org
Subject:   svn commit: r331866 - stable/11/sys/x86/x86
Message-ID:  <201804011642.w31GgDXV037410@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: markj
Date: Sun Apr  1 16:42:13 2018
New Revision: 331866
URL: https://svnweb.freebsd.org/changeset/base/331866

Log:
  MFC r317567 (by cem):
  x86 MCA: Fix a deadlock in MCA exception processing

Modified:
  stable/11/sys/x86/x86/mca.c
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/sys/x86/x86/mca.c
==============================================================================
--- stable/11/sys/x86/x86/mca.c	Sun Apr  1 07:49:48 2018	(r331865)
+++ stable/11/sys/x86/x86/mca.c	Sun Apr  1 16:42:13 2018	(r331866)
@@ -653,7 +653,7 @@ amd_thresholding_update(enum scan_mode mode, int bank,
  * count of the number of valid MC records found.
  */
 static int
-mca_scan(enum scan_mode mode)
+mca_scan(enum scan_mode mode, int *recoverablep)
 {
 	struct mca_record rec;
 	uint64_t mcg_cap, ucmask;
@@ -704,7 +704,9 @@ mca_scan(enum scan_mode mode)
 	}
 	if (mode == POLLED)
 		mca_fill_freelist();
-	return (mode == MCE ? recoverable : count);
+	if (recoverablep != NULL)
+		*recoverablep = recoverable;
+	return (count);
 }
 
 /*
@@ -726,7 +728,7 @@ mca_scan_cpus(void *context, int pending)
 	CPU_FOREACH(cpu) {
 		sched_bind(td, cpu);
 		thread_unlock(td);
-		count += mca_scan(POLLED);
+		count += mca_scan(POLLED, NULL);
 		thread_lock(td);
 		sched_unbind(td);
 	}
@@ -1150,7 +1152,7 @@ void
 mca_intr(void)
 {
 	uint64_t mcg_status;
-	int old_count, recoverable;
+	int recoverable, count;
 
 	if (!(cpu_feature & CPUID_MCA)) {
 		/*
@@ -1164,20 +1166,18 @@ mca_intr(void)
 	}
 
 	/* Scan the banks and check for any non-recoverable errors. */
-	old_count = mca_count;
-	recoverable = mca_scan(MCE);
+	count = mca_scan(MCE, &recoverable);
 	mcg_status = rdmsr(MSR_MCG_STATUS);
 	if (!(mcg_status & MCG_STATUS_RIPV))
 		recoverable = 0;
 
 	if (!recoverable) {
 		/*
-		 * Wait for at least one error to be logged before
-		 * panic'ing.  Some errors will assert a machine check
-		 * on all CPUs, but only certain CPUs will find a valid
-		 * bank to log.
+		 * Only panic if the error was detected local to this CPU.
+		 * Some errors will assert a machine check on all CPUs, but
+		 * only certain CPUs will find a valid bank to log.
 		 */
-		while (mca_count == old_count)
+		while (count == 0)
 			cpu_spinwait();
 
 		panic("Unrecoverable machine check exception");
@@ -1199,7 +1199,7 @@ cmc_intr(void)
 	 * Serialize MCA bank scanning to prevent collisions from
 	 * sibling threads.
 	 */
-	count = mca_scan(CMCI);
+	count = mca_scan(CMCI, NULL);
 
 	/* If we found anything, log them to the console. */
 	if (count != 0) {



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201804011642.w31GgDXV037410>