diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 16620146c49a9f1cedd208e3f74abc99b2ab5673..05302e1d8e1904dfcc42bc5357a15600eff65ade 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -86,6 +86,7 @@ config ARM64 select ARCH_WANT_HUGETLB_PAGE_OPTIMIZE_VMEMMAP select ARCH_WANT_LD_ORPHAN_WARN select ARCH_WANT_RESERVE_CRASH_KERNEL if KEXEC_CORE + select ARCH_WANTS_THP_SWAP if ARM64_4K_PAGES select ARCH_HAS_UBSAN_SANITIZE_ALL select ARM_AMBA select ARM_ARCH_TIMER diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h index ab2443900f4eaee19a9b216ab09ecdf09f58d1ac..f2843785f2ec7021bb7bd2e25b7baaffb7e38e64 100644 --- a/arch/arm64/include/asm/pgtable.h +++ b/arch/arm64/include/asm/pgtable.h @@ -46,6 +46,12 @@ __flush_tlb_range(vma, addr, end, PUD_SIZE, false, 1) #endif /* CONFIG_TRANSPARENT_HUGEPAGE */ +static inline bool arch_thp_swp_supported(void) +{ + return !system_supports_mte(); +} +#define arch_thp_swp_supported arch_thp_swp_supported + /* * Outside of a few very special situations (e.g. hibernation), we always * use broadcast TLB invalidation instructions, therefore a spurious page diff --git a/include/linux/huge_mm.h b/include/linux/huge_mm.h index 176457145bcf2a7205e60401086951d1b5342603..b993ae44111c007b54cee4ba3a530062062af2a1 100644 --- a/include/linux/huge_mm.h +++ b/include/linux/huge_mm.h @@ -499,4 +499,16 @@ static inline unsigned long thp_size(struct page *page) return PAGE_SIZE << thp_order(page); } +/* + * archs that select ARCH_WANTS_THP_SWAP but don't support THP_SWP due to + * limitations in the implementation like arm64 MTE can override this to + * false + */ +#ifndef arch_thp_swp_supported +static inline bool arch_thp_swp_supported(void) +{ + return true; +} +#endif + #endif /* _LINUX_HUGE_MM_H */ diff --git a/mm/swap_slots.c b/mm/swap_slots.c index fbb9888a0469a48b19d706654479eed59893b1f8..b7958ca276c25e2c49ea1f55879b3215730f32a8 100644 --- a/mm/swap_slots.c +++ b/mm/swap_slots.c @@ -436,7 +436,7 @@ swp_entry_t get_swap_page(struct page *page) goto out; if (PageTransHuge(page)) { - if (IS_ENABLED(CONFIG_THP_SWAP)) + if (IS_ENABLED(CONFIG_THP_SWAP) && arch_thp_swp_supported()) get_swap_pages(1, &entry, HPAGE_PMD_NR, type); goto out; }