Skip to content

Commit e43c0a0

Browse files
npigginmpe
authored andcommitted
powerpc/64s/radix: combine final TLB flush and lazy tlb mm shootdown IPIs
This performs lazy tlb mm shootdown when doing the exit TLB flush when all mm users go away and user mappings are removed, which avoids having to do the lazy tlb mm shootdown IPIs on the final mmput when all kernel references disappear. powerpc/64s uses a broadcast TLBIE for the exit TLB flush if remote CPUs need to be invalidated (unless TLBIE is disabled), so this doesn't necessarily save IPIs but it does avoid a broadcast TLBIE which is quite expensive. Signed-off-by: Nicholas Piggin <[email protected]> [mpe: Squash in preempt_disable/enable() fix from Nick] Signed-off-by: Michael Ellerman <[email protected]> Link: https://msgid.link/[email protected]
1 parent 177255a commit e43c0a0

File tree

1 file changed

+29
-1
lines changed

1 file changed

+29
-1
lines changed

arch/powerpc/mm/book3s64/radix_tlb.c

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1313,7 +1313,35 @@ void radix__tlb_flush(struct mmu_gather *tlb)
13131313
* See the comment for radix in arch_exit_mmap().
13141314
*/
13151315
if (tlb->fullmm) {
1316-
__flush_all_mm(mm, true);
1316+
if (IS_ENABLED(CONFIG_MMU_LAZY_TLB_SHOOTDOWN)) {
1317+
/*
1318+
* Shootdown based lazy tlb mm refcounting means we
1319+
* have to IPI everyone in the mm_cpumask anyway soon
1320+
* when the mm goes away, so might as well do it as
1321+
* part of the final flush now.
1322+
*
1323+
* If lazy shootdown was improved to reduce IPIs (e.g.,
1324+
* by batching), then it may end up being better to use
1325+
* tlbies here instead.
1326+
*/
1327+
preempt_disable();
1328+
1329+
smp_mb(); /* see radix__flush_tlb_mm */
1330+
exit_flush_lazy_tlbs(mm);
1331+
_tlbiel_pid(mm->context.id, RIC_FLUSH_ALL);
1332+
1333+
/*
1334+
* It should not be possible to have coprocessors still
1335+
* attached here.
1336+
*/
1337+
if (WARN_ON_ONCE(atomic_read(&mm->context.copros) > 0))
1338+
__flush_all_mm(mm, true);
1339+
1340+
preempt_enable();
1341+
} else {
1342+
__flush_all_mm(mm, true);
1343+
}
1344+
13171345
} else if ( (psize = radix_get_mmu_psize(page_size)) == -1) {
13181346
if (!tlb->freed_tables)
13191347
radix__flush_tlb_mm(mm);

0 commit comments

Comments
 (0)