This is a repost of the mremap speed up patches, adding Kirill's Acked-by's (from a separate discussion). The previous versions are posted at: v1 - https://lore.kernel.org/r/20200930222130.4175584-1-kaleshsingh@google.com v2 - https://lore.kernel.org/r/20201002162101.665549-1-kaleshsingh@google.com v3 - http://lore.kernel.org/r/20201005154017.474722-1-kaleshsingh@google.com
mremap time can be optimized by moving entries at the PMD/PUD level if the source and destination addresses are PMD/PUD-aligned and PMD/PUD-sized. Enable moving at the PMD and PUD levels on arm64 and x86. Other architectures where this type of move is supported and known to be safe can also opt-in to these optimizations by enabling HAVE_MOVE_PMD and HAVE_MOVE_PUD.
Observed Performance Improvements for remapping a PUD-aligned 1GB-sized region on x86 and arm64:
- HAVE_MOVE_PMD is already enabled on x86 : N/A - Enabling HAVE_MOVE_PUD on x86 : ~13x speed up
- Enabling HAVE_MOVE_PMD on arm64 : ~ 8x speed up - Enabling HAVE_MOVE_PUD on arm64 : ~19x speed up
Altogether, HAVE_MOVE_PMD and HAVE_MOVE_PUD give a total of ~150x speed up on arm64.
Changes in v2: - Reduce mremap_test time by only validating a configurable threshold of the remapped region, as per John. - Use a random pattern for mremap validation. Provide pattern seed in test output, as per John. - Moved set_pud_at() to separate patch, per Kirill. - Use switch() instead of ifs in move_pgt_entry(), per Kirill. - Update commit message with description of Android garbage collector use case for HAVE_MOVE_PUD, as per Joel. - Fix build test error reported by kernel test robot in [1].
Changes in v3: - Make lines 80 cols or less where they don’t need to be longer, per John. - Removed unused PATTERN_SIZE in mremap_test - Added Reviewed-by tag for patch 1/5 (mremap kselftest patch). - Use switch() instead of ifs in get_extent(), per Kirill - Add BUILD_BUG() is get_extent() default case. - Move get_old_pud() and alloc_new_pud() out of #ifdef CONFIG_HAVE_MOVE_PUD, per Kirill. - Have get_old_pmd() and alloc_new_pmd() use get_old_pud() and alloc_old_pud(), per Kirill. - Replace #ifdef CONFIG_HAVE_MOVE_PMD / PUD in move_page_tables() with IS_ENABLED(CONFIG_HAVE_MOVE_PMD / PUD), per Kirill. - Fold Add set_pud_at() patch into patch 4/5, per Kirill.
[1] https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org/thread/CKPGL4FH...
Kalesh Singh (5): kselftests: vm: Add mremap tests arm64: mremap speedup - Enable HAVE_MOVE_PMD mm: Speedup mremap on 1GB or larger regions arm64: mremap speedup - Enable HAVE_MOVE_PUD x86: mremap speedup - Enable HAVE_MOVE_PUD
arch/Kconfig | 7 + arch/arm64/Kconfig | 2 + arch/arm64/include/asm/pgtable.h | 1 + arch/x86/Kconfig | 1 + mm/mremap.c | 230 ++++++++++++--- tools/testing/selftests/vm/.gitignore | 1 + tools/testing/selftests/vm/Makefile | 1 + tools/testing/selftests/vm/mremap_test.c | 344 +++++++++++++++++++++++ tools/testing/selftests/vm/run_vmtests | 11 + 9 files changed, 558 insertions(+), 40 deletions(-) create mode 100644 tools/testing/selftests/vm/mremap_test.c