Re: [PATCH] arm64/mm: Optimize TLB flush in unmap_hotplug_[pmd|pud]_range()
From: Will Deacon
Date: Mon Jun 29 2026 - 07:19:45 EST
On Fri, Jun 26, 2026 at 06:09:27PM +0200, David Hildenbrand (Arm) wrote:
> On 6/26/26 03:28, Anshuman Khandual wrote:
> > flush_tlb_kernel_range() could flush down an entire block mapping just with
> > a single PAGE_SIZE stride. This capability was being used umapping PMD and
> > PUD based block mappings in unmap_hotplug_[pmd|pud]_range().
> >
> > But later on the commit 48478b9f7913
> > ("arm64/mm: Enable batched TLB flush in unmap_hotplug_range()") replaced
> > this PAGE_SIZE stride with [PMD|PUD]_SIZE strides, hence forcing multiple
> > PAGE_SIZE stride based TLB flushes on platforms where TLB range operation
> > is not supported. Revert back to the earlier TLB behaviour along with the
> > required comments that were dropped earlier.
> >
>
> Right, it looked like the right thing to do in that commit. I wonder if we can
> make the comments even clearer to prevent his happening another time,
> incorporating the HW consideration.
>
> In any case
>
> Reviewed-by: David Hildenbrand (Arm) <david@xxxxxxxxxx>
>
> > Cc: Catalin Marinas <catalin.marinas@xxxxxxx>
> > Cc: Will Deacon <will@xxxxxxxxxx>
> > Cc: Ryan Roberts <ryan.roberts@xxxxxxx>
> > Cc: David Hildenbrand <david@xxxxxxxxxx>
> > Cc: linux-arm-kernel@xxxxxxxxxxxxxxxxxxx
> > Cc: linux-kernel@xxxxxxxxxxxxxxx
> > Reported-by: Ben Hutchings <ben@xxxxxxxxxxxxxxx>
> > Closes: https://lore.kernel.org/all/b0d5836032ce3135bfc473f6bff791306d086925.camel@xxxxxxxxxxxxxxx/
> > Fixes: 48478b9f7913 ("arm64/mm: Enable batched TLB flush in unmap_hotplug_range()")
> > Signed-off-by: Anshuman Khandual <anshuman.khandual@xxxxxxx>
> > ---
> > arch/arm64/mm/mmu.c | 12 ++++++++++--
> > 1 file changed, 10 insertions(+), 2 deletions(-)
> >
> > diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
> > index 8242f93f05e4..5ff0041f4a5f 100644
> > --- a/arch/arm64/mm/mmu.c
> > +++ b/arch/arm64/mm/mmu.c
> > @@ -1509,7 +1509,11 @@ static void unmap_hotplug_pmd_range(pud_t *pudp, unsigned long addr,
> > if (free_mapped) {
> > /* CONT blocks are not supported in the vmemmap */
> > WARN_ON(pmd_cont(pmd));
> > - flush_tlb_kernel_range(addr, addr + PMD_SIZE);
> > + /*
> > + * One TLBI should be sufficient here as the PMD_SIZE
> > + * range is mapped with a single block entry.
> > + */
>
> "Flush only a single page, resulting in a single TLBi for this large block
> mapping, avoiding multiple TLBIs on HW without TLB range flushes."
I'll add something like this when applying and I'll rewrite the commit
message as well.
Cheers,
Will