-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
riscv: move switch_mm to its own file
switch_mm is an expensive operations that has two users. flush_icache_deferred is only called within switch_mm and can be moved together. The function is expected to be more complicated when ASID support is added, so clean up eagerly. By moving them to a separate file we also removes some excessive dependency of tlbflush.h and cacheflush.h. Signed-off-by: Gary Guo <gary@garyguo.net> Reviewed-by: Anup Patel <anup@brainfault.org> Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Palmer Dabbelt <palmer@sifive.com>
- Loading branch information
Gary Guo
authored and
Palmer Dabbelt
committed
May 17, 2019
1 parent
58de775
commit f6635f8
Showing
3 changed files
with
72 additions
and
52 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,3 +9,4 @@ obj-y += fault.o | |
obj-y += extable.o | ||
obj-y += ioremap.o | ||
obj-y += cacheflush.o | ||
obj-y += context.o |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
// SPDX-License-Identifier: GPL-2.0 | ||
/* | ||
* Copyright (C) 2012 Regents of the University of California | ||
* Copyright (C) 2017 SiFive | ||
*/ | ||
|
||
#include <linux/mm.h> | ||
#include <asm/tlbflush.h> | ||
#include <asm/cacheflush.h> | ||
|
||
/* | ||
* When necessary, performs a deferred icache flush for the given MM context, | ||
* on the local CPU. RISC-V has no direct mechanism for instruction cache | ||
* shoot downs, so instead we send an IPI that informs the remote harts they | ||
* need to flush their local instruction caches. To avoid pathologically slow | ||
* behavior in a common case (a bunch of single-hart processes on a many-hart | ||
* machine, ie 'make -j') we avoid the IPIs for harts that are not currently | ||
* executing a MM context and instead schedule a deferred local instruction | ||
* cache flush to be performed before execution resumes on each hart. This | ||
* actually performs that local instruction cache flush, which implicitly only | ||
* refers to the current hart. | ||
*/ | ||
static inline void flush_icache_deferred(struct mm_struct *mm) | ||
{ | ||
#ifdef CONFIG_SMP | ||
unsigned int cpu = smp_processor_id(); | ||
cpumask_t *mask = &mm->context.icache_stale_mask; | ||
|
||
if (cpumask_test_cpu(cpu, mask)) { | ||
cpumask_clear_cpu(cpu, mask); | ||
/* | ||
* Ensure the remote hart's writes are visible to this hart. | ||
* This pairs with a barrier in flush_icache_mm. | ||
*/ | ||
smp_mb(); | ||
local_flush_icache_all(); | ||
} | ||
|
||
#endif | ||
} | ||
|
||
void switch_mm(struct mm_struct *prev, struct mm_struct *next, | ||
struct task_struct *task) | ||
{ | ||
unsigned int cpu; | ||
|
||
if (unlikely(prev == next)) | ||
return; | ||
|
||
/* | ||
* Mark the current MM context as inactive, and the next as | ||
* active. This is at least used by the icache flushing | ||
* routines in order to determine who should be flushed. | ||
*/ | ||
cpu = smp_processor_id(); | ||
|
||
cpumask_clear_cpu(cpu, mm_cpumask(prev)); | ||
cpumask_set_cpu(cpu, mm_cpumask(next)); | ||
|
||
/* | ||
* Use the old spbtr name instead of using the current satp | ||
* name to support binutils 2.29 which doesn't know about the | ||
* privileged ISA 1.10 yet. | ||
*/ | ||
csr_write(sptbr, virt_to_pfn(next->pgd) | SATP_MODE); | ||
local_flush_tlb_all(); | ||
|
||
flush_icache_deferred(next); | ||
} |