Skip to content

Commit 0a4118d

Browse files
tjy-zhuopsiff
authored andcommitted
sw64: add support for batched TLB flushing during unmap
This patch enables ARCH_WANT_BATCHED_UNMAP_TLB_FLUSH for sw64 architecture. By deferring TLB flushes during memory reclamation, we can significantly reduce the number of Inter-Processor Interrupts (IPIs) sent between cores. This is highly beneficial in multi-threaded workloads sharing the same memory space, preventing IPI storms when swapping out pages actively cached in multiple CPUs. Signed-off-by: Jinyu Tang <tjytimi@163.com> Signed-off-by: Gu Yuchen <guyuchen@wxiat.com> Reviewed-by: He Sheng <hesheng@wxiat.com> Signed-off-by: Gu Zitao <guzitao@wxiat.com>
1 parent 14be57c commit 0a4118d

4 files changed

Lines changed: 54 additions & 0 deletions

File tree

arch/sw_64/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ config SW64
5959
select ARCH_USE_CMPXCHG_LOCKREF
6060
select ARCH_USE_QUEUED_RWLOCKS
6161
select ARCH_USE_QUEUED_SPINLOCKS
62+
select ARCH_WANT_BATCHED_UNMAP_TLB_FLUSH
6263
select ARCH_WANT_DEFAULT_BPF_JIT
6364
select ARCH_WANT_FRAME_POINTERS
6465
select ARCH_WANT_IPC_PARSE_VERSION

arch/sw_64/include/asm/tlbbatch.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
/* SPDX-License-Identifier: GPL-2.0-only */
2+
#ifndef _ASM_SW_64_TLBBATCH_H
3+
#define _ASM_SW_64_TLBBATCH_H
4+
5+
#include <linux/cpumask.h>
6+
7+
struct arch_tlbflush_unmap_batch {
8+
struct cpumask cpumask;
9+
};
10+
11+
#endif /* _ASM_SW_64_TLBBATCH_H */

arch/sw_64/include/asm/tlbflush.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,4 +91,28 @@ extern void flush_tlb_kernel_range(unsigned long start, unsigned long end);
9191

9292
#endif /* CONFIG_SMP */
9393

94+
95+
static inline bool arch_tlbbatch_should_defer(struct mm_struct *mm)
96+
{
97+
bool should_defer = false;
98+
99+
/* If remote CPUs need to be flushed then defer batch the flush */
100+
if (cpumask_any_but(mm_cpumask(mm), get_cpu()) < nr_cpu_ids)
101+
should_defer = true;
102+
put_cpu();
103+
104+
return should_defer;
105+
}
106+
107+
static inline void arch_flush_tlb_batched_pending(struct mm_struct *mm)
108+
{
109+
flush_tlb_mm(mm);
110+
}
111+
112+
extern void arch_tlbbatch_add_pending(struct arch_tlbflush_unmap_batch *batch,
113+
struct mm_struct *mm,
114+
unsigned long uaddr);
115+
extern void arch_tlbbatch_flush(struct arch_tlbflush_unmap_batch *batch);
116+
117+
94118
#endif /* _ASM_SW64_TLBFLUSH_H */

arch/sw_64/kernel/smp.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <linux/cpu.h>
1111
#include <linux/acpi.h>
1212
#include <linux/of.h>
13+
#include <linux/mmu_notifier.h>
1314

1415
#include <asm/irq_impl.h>
1516
#include <asm/mmu.h>
@@ -821,6 +822,23 @@ void flush_tlb_kernel_range(unsigned long start, unsigned long end)
821822
}
822823
EXPORT_SYMBOL(flush_tlb_kernel_range);
823824

825+
void arch_tlbbatch_add_pending(struct arch_tlbflush_unmap_batch *batch,
826+
struct mm_struct *mm,
827+
unsigned long uaddr)
828+
{
829+
cpumask_or(&batch->cpumask, &batch->cpumask, mm_cpumask(mm));
830+
831+
mmu_notifier_arch_invalidate_secondary_tlbs(mm, 0, -1UL);
832+
}
833+
834+
void arch_tlbbatch_flush(struct arch_tlbflush_unmap_batch *batch)
835+
{
836+
if (!cpumask_empty(&batch->cpumask)) {
837+
on_each_cpu_mask(&batch->cpumask, ipi_flush_tlb_all, NULL, 1);
838+
cpumask_clear(&batch->cpumask);
839+
}
840+
}
841+
824842
#ifdef CONFIG_HOTPLUG_CPU
825843
extern int can_unplug_cpu(void);
826844
int __cpu_disable(void)

0 commit comments

Comments
 (0)