Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 27 Apr 2014 20:16:51 +0000 (UTC)
From:      Ian Lepore <ian@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r265024 - head/sys/arm/arm
Message-ID:  <201404272016.s3RKGpMi023604@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: ian
Date: Sun Apr 27 20:16:51 2014
New Revision: 265024
URL: http://svnweb.freebsd.org/changeset/base/265024

Log:
  Flush and invalidate caches on each CPU as part of handling IPI_STOP.
  
  Flushing the caches is required before doing a panic dump, but ARM
  doesn't provide a flavor of flush that gets broadcast to other cores.
  However, all cores except one are stopped before doing a dump, so this
  works around the lack of a global flush/invalidate by doing it locally
  on each CPU as part of stopping.
  
  Discussed with:	cognet@

Modified:
  head/sys/arm/arm/minidump_machdep.c
  head/sys/arm/arm/mp_machdep.c

Modified: head/sys/arm/arm/minidump_machdep.c
==============================================================================
--- head/sys/arm/arm/minidump_machdep.c	Sun Apr 27 20:01:59 2014	(r265023)
+++ head/sys/arm/arm/minidump_machdep.c	Sun Apr 27 20:16:51 2014	(r265024)
@@ -210,7 +210,15 @@ minidumpsys(struct dumperinfo *di)
 	int i, k, bit, error;
 	char *addr;
 
-	/* Flush cache */
+	/*
+	 * Flush caches.  Note that in the SMP case this operates only on the
+	 * current CPU's L1 cache.  Before we reach this point, code in either
+	 * the system shutdown or kernel debugger has called stop_cpus() to stop
+	 * all cores other than this one.  Part of the ARM handling of
+	 * stop_cpus() is to call wbinv_all() on that core's local L1 cache.  So
+	 * by time we get to here, all that remains is to flush the L1 for the
+	 * current CPU, then the L2.
+	 */
 	cpu_idcache_wbinv_all();
 	cpu_l2cache_wbinv_all();
 

Modified: head/sys/arm/arm/mp_machdep.c
==============================================================================
--- head/sys/arm/arm/mp_machdep.c	Sun Apr 27 20:01:59 2014	(r265023)
+++ head/sys/arm/arm/mp_machdep.c	Sun Apr 27 20:16:51 2014	(r265024)
@@ -44,6 +44,7 @@ __FBSDID("$FreeBSD$");
 #include <vm/pmap.h>
 
 #include <machine/cpu.h>
+#include <machine/cpufunc.h>
 #include <machine/smp.h>
 #include <machine/pcb.h>
 #include <machine/pte.h>
@@ -286,6 +287,19 @@ ipi_handler(void *arg)
 
 			savectx(&stoppcbs[cpu]);
 
+			/*
+			 * CPUs are stopped when entering the debugger and at
+			 * system shutdown, both events which can precede a
+			 * panic dump.  For the dump to be correct, all caches
+			 * must be flushed and invalidated, but on ARM there's
+			 * no way to broadcast a wbinv_all to other cores.
+			 * Instead, we have each core do the local wbinv_all as
+			 * part of stopping the core.  The core requesting the
+			 * stop will do the l2 cache flush after all other cores
+			 * have done their l1 flushes and stopped.
+			 */
+			cpu_idcache_wbinv_all();
+
 			/* Indicate we are stopped */
 			CPU_SET_ATOMIC(cpu, &stopped_cpus);
 



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