[PATCH] LoongArch: align range before sizing in local_flush_tlb_kernel_range
From: Song Hu
Date: Thu Jul 16 2026 - 23:28:10 EST
local_flush_tlb_kernel_range() sizes the flush from the unaligned caller
range and aligns start/end only afterwards — the opposite order of its
sibling local_flush_tlb_range(), which aligns first. Align start/end
first, then size, to match the sibling.
The order matters for unaligned ranges: the original size is derived from
the raw caller range, not the 2-page-aligned range the per-entry invtlb()
loop actually iterates, so it can fall one entry short, and the
tlbsize/8-vs-tlbsize/2 threshold may then pick the per-entry loop when a
full local_flush_tlb_kernel() would be cheaper.
Both strategies flush correctly; the change only makes the sizing heuristic
match the sibling and reflect the real flush count.
Signed-off-by: Song Hu <husong@xxxxxxxxxx>
---
arch/loongarch/mm/tlb.c | 11 ++++-------
1 file changed, 4 insertions(+), 7 deletions(-)
diff --git a/arch/loongarch/mm/tlb.c b/arch/loongarch/mm/tlb.c
index 4b3d7120da73..a3c90841edbd 100644
--- a/arch/loongarch/mm/tlb.c
+++ b/arch/loongarch/mm/tlb.c
@@ -90,16 +90,13 @@ void local_flush_tlb_kernel_range(unsigned long start, unsigned long end)
unsigned long size, flags;
local_irq_save(flags);
- size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
- size = (size + 1) >> 1;
+ start &= (PAGE_MASK << 1);
+ end += ((PAGE_SIZE << 1) - 1);
+ end &= (PAGE_MASK << 1);
+ size = (end - start) >> (PAGE_SHIFT + 1);
if (size <= (current_cpu_data.tlbsizestlbsets ?
current_cpu_data.tlbsize / 8 :
current_cpu_data.tlbsize / 2)) {
-
- start &= (PAGE_MASK << 1);
- end += ((PAGE_SIZE << 1) - 1);
- end &= (PAGE_MASK << 1);
-
while (start < end) {
invtlb_addr(INVTLB_ADDR_GTRUE_OR_ASID, 0, start);
start += (PAGE_SIZE << 1);
--
2.43.0