mirror of
https://github.com/freebsd/freebsd-src.git
synced 2024-12-04 05:58:57 +00:00
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@
This commit is contained in:
parent
824e4131a0
commit
fa046341af
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=265024
@ -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();
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user