Although THP-granularity exec COW can reduce the number of faults and improve iTLB hit rates, but after enabling it, the THP folio allocating and copying operations may introduce higher latency, and it consumes more memory compared to page COW handling. These side effects may be unacceptable in certain scenarios. Therefore, we add use_exec_cow sysfs knob for THP COW of executable private file mmap. It's enabled by default, kernel will try to allocate PMD page and map it. If it's disabled, it will fallback to split PMD mapping and do pte fault handle. Signed-off-by: Zhang Qilong --- Documentation/admin-guide/mm/transhuge.rst | 8 ++++++++ include/linux/huge_mm.h | 4 ++++ mm/huge_memory.c | 18 +++++++++++++++++- mm/memory.c | 3 ++- 4 files changed, 31 insertions(+), 2 deletions(-) diff --git a/Documentation/admin-guide/mm/transhuge.rst b/Documentation/admin-guide/mm/transhuge.rst index 5fbc3d89bb07..c6d7ca045c03 100644 --- a/Documentation/admin-guide/mm/transhuge.rst +++ b/Documentation/admin-guide/mm/transhuge.rst @@ -201,10 +201,18 @@ page fault to anonymous mapping. It's possible to disable huge zero page by writing 0 or enable it back by writing 1:: echo 0 >/sys/kernel/mm/transparent_hugepage/use_zero_page echo 1 >/sys/kernel/mm/transparent_hugepage/use_zero_page +By default kernel tries to use huge, PMD-mappable page on private +executable file THP mmap fault handle. It's possible to disable +THP COW of private executable mmap by writing 0 or enable it back +by writing 1:: + + echo 0 >/sys/kernel/mm/transparent_hugepage/use_exec_cow + echo 1 >/sys/kernel/mm/transparent_hugepage/use_exec_cow + Some userspace (such as a test program, or an optimized memory allocation library) may want to know the size (in bytes) of a PMD-mappable transparent hugepage:: cat /sys/kernel/mm/transparent_hugepage/hpage_pmd_size diff --git a/include/linux/huge_mm.h b/include/linux/huge_mm.h index bae856a53e1f..d86215f06ac9 100644 --- a/include/linux/huge_mm.h +++ b/include/linux/huge_mm.h @@ -55,10 +55,11 @@ enum transparent_hugepage_flag { TRANSPARENT_HUGEPAGE_DEFRAG_KSWAPD_FLAG, TRANSPARENT_HUGEPAGE_DEFRAG_KSWAPD_OR_MADV_FLAG, TRANSPARENT_HUGEPAGE_DEFRAG_REQ_MADV_FLAG, TRANSPARENT_HUGEPAGE_DEFRAG_KHUGEPAGED_FLAG, TRANSPARENT_HUGEPAGE_USE_ZERO_PAGE_FLAG, + TRANSPARENT_HUGEPAGE_USE_EXEC_COW_FLAG, }; struct kobject; struct kobj_attribute; @@ -323,10 +324,13 @@ struct thpsize { #define transparent_hugepage_use_zero_page() \ (transparent_hugepage_flags & \ (1<vm_flags) && + if (transparent_hugepage_use_exec_cow() && + is_exec_mapping(vma->vm_flags) && is_cow_mapping(vma->vm_flags)) { /* Skip special and shmem */ if (vma_is_special_huge(vma) || vma_is_shmem(vma)) goto split; -- 2.43.0