Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 24 Feb 2017 18:56:01 +0000 (UTC)
From:      "Jonathan T. Looney" <jtl@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r314216 - head/sys/x86/x86
Message-ID:  <201702241856.v1OIu150004903@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: jtl
Date: Fri Feb 24 18:56:00 2017
New Revision: 314216
URL: https://svnweb.freebsd.org/changeset/base/314216

Log:
  We have seen several cases recently where we appear to get a double-fault:
  We have an original panic. Then, instead of writing the core to the dump
  device, the kernel has a second panic: "smp_targeted_tlb_shootdown:
  interrupts disabled". This change is an attempt to fix that second panic.
  
  When the other CPUs are stopped, we can't notify them of the TLB shootdown,
  so we skip that operation. However, when the CPUs come back up, we
  invalidate the TLB to ensure they correctly observe any changes to the
  page mappings.
  
  Reviewed by:	kib
  Sponsored by:	Netflix
  Differential Revision:	https://reviews.freebsd.org/D9786

Modified:
  head/sys/x86/x86/mp_x86.c

Modified: head/sys/x86/x86/mp_x86.c
==============================================================================
--- head/sys/x86/x86/mp_x86.c	Fri Feb 24 17:36:55 2017	(r314215)
+++ head/sys/x86/x86/mp_x86.c	Fri Feb 24 18:56:00 2017	(r314216)
@@ -45,6 +45,7 @@ __FBSDID("$FreeBSD$");
 #ifdef GPROF 
 #include <sys/gmon.h>
 #endif
+#include <sys/kdb.h>
 #include <sys/kernel.h>
 #include <sys/ktr.h>
 #include <sys/lock.h>
@@ -1269,6 +1270,12 @@ cpustop_handler_post(u_int cpu)
 	CPU_CLR_ATOMIC(cpu, &started_cpus);
 	CPU_CLR_ATOMIC(cpu, &stopped_cpus);
 
+	/*
+	 * We don't broadcast TLB invalidations to other CPUs when they are
+	 * stopped. Hence, we clear the TLB before resuming.
+	 */
+	invltlb_glob();
+
 #if defined(__amd64__) && defined(DDB)
 	amd64_db_resume_dbreg();
 #endif
@@ -1427,6 +1434,10 @@ smp_targeted_tlb_shootdown(cpuset_t mask
 	uint32_t generation;
 	int cpu;
 
+	/* It is not necessary to signal other CPUs while in the debugger. */
+	if (kdb_active || panicstr != NULL)
+		return;
+
 	/*
 	 * Check for other cpus.  Return if none.
 	 */



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