Re: [PATCH v2 2/2] mm: speed up mremap by 500x on large regions
From: Kirill A. Shutemov <hidden>
Date: 2018-10-12 11:31:03
Also in:
kvmarm, linux-alpha, linux-mips, linux-mm, linux-riscv, linux-s390, linux-um
On Thu, Oct 11, 2018 at 06:37:56PM -0700, Joel Fernandes (Google) wrote:
Android needs to mremap large regions of memory during memory management related operations. The mremap system call can be really slow if THP is not enabled. The bottleneck is move_page_tables, which is copying each pte at a time, and can be really slow across a large map. Turning on THP may not be a viable option, and is not for us. This patch speeds up the performance for non-THP system by copying at the PMD level when possible. The speed up is three orders of magnitude. On a 1GB mremap, the mremap completion times drops from 160-250 millesconds to 380-400 microseconds. Before: Total mremap time for 1GB data: 242321014 nanoseconds. Total mremap time for 1GB data: 196842467 nanoseconds. Total mremap time for 1GB data: 167051162 nanoseconds. After: Total mremap time for 1GB data: 385781 nanoseconds. Total mremap time for 1GB data: 388959 nanoseconds. Total mremap time for 1GB data: 402813 nanoseconds. Incase THP is enabled, the optimization is skipped. I also flush the tlb every time we do this optimization since I couldn't find a way to determine if the low-level PTEs are dirty. It is seen that the cost of doing so is not much compared the improvement, on both x86-64 and arm64.
I looked into the code more and noticed move_pte() helper called from move_ptes(). It changes PTE entry to suite new address. It is only defined in non-trivial way on Sparc. I don't know much about Sparc and it's hard for me to say if the optimization will break anything there. I think it worth to disable the optimization if __HAVE_ARCH_MOVE_PTE is defined. Or make architectures state explicitely that the optimization is safe.
quoted hunk ↗ jump to hunk
@@ -239,7 +287,21 @@ unsigned long move_page_tables(struct vm_area_struct *vma, split_huge_pmd(vma, old_pmd, old_addr); if (pmd_trans_unstable(old_pmd)) continue; + } else if (extent == PMD_SIZE) {
Hm. What guarantees that new_addr is PMD_SIZE-aligned? It's not obvious to me. -- Kirill A. Shutemov