]> git.ipfire.org Git - thirdparty/kernel/linux.git/commit
arm64/mm: Batch barriers when updating kernel mappings
authorRyan Roberts <ryan.roberts@arm.com>
Tue, 22 Apr 2025 08:18:19 +0000 (09:18 +0100)
committerWill Deacon <will@kernel.org>
Fri, 9 May 2025 12:43:08 +0000 (13:43 +0100)
commit5fdd05efa1cd3bb98060f409eca57dc0a6d171b4
tree2db4ebbc2d30831fd0337e45ce3adf75cd45ec09
parent44562c71e2cfc9eed39bfcd98af63d5da8b1b5bf
arm64/mm: Batch barriers when updating kernel mappings

Because the kernel can't tolerate page faults for kernel mappings, when
setting a valid, kernel space pte (or pmd/pud/p4d/pgd), it emits a
dsb(ishst) to ensure that the store to the pgtable is observed by the
table walker immediately. Additionally it emits an isb() to ensure that
any already speculatively determined invalid mapping fault gets
canceled.

We can improve the performance of vmalloc operations by batching these
barriers until the end of a set of entry updates.
arch_enter_lazy_mmu_mode() and arch_leave_lazy_mmu_mode() provide the
required hooks.

vmalloc improves by up to 30% as a result.

Two new TIF_ flags are created; TIF_LAZY_MMU tells us if the task is in
the lazy mode and can therefore defer any barriers until exit from the
lazy mode. TIF_LAZY_MMU_PENDING is used to remember if any pte operation
was performed while in the lazy mode that required barriers. Then when
leaving lazy mode, if that flag is set, we emit the barriers.

Since arch_enter_lazy_mmu_mode() and arch_leave_lazy_mmu_mode() are used
for both user and kernel mappings, we need the second flag to avoid
emitting barriers unnecessarily if only user mappings were updated.

Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Ryan Roberts <ryan.roberts@arm.com>
Reviewed-by: Anshuman Khandual <anshuman.khandual@arm.com>
Tested-by: Luiz Capitulino <luizcap@redhat.com>
Link: https://lore.kernel.org/r/20250422081822.1836315-12-ryan.roberts@arm.com
Signed-off-by: Will Deacon <will@kernel.org>
arch/arm64/include/asm/pgtable.h
arch/arm64/include/asm/thread_info.h
arch/arm64/kernel/process.c