From: Kiryl Shutsemau The finish_fault() function uses per-page fault for file folios. This only occurs for file folios smaller than PMD_SIZE. The comment suggests that this approach prevents RSS inflation. However, it only prevents RSS accounting. The folio is still mapped to the process, and the fact that it is mapped by a single PTE does not affect memory pressure. Additionally, the kernel's ability to map large folios as PMD if they are large enough does not support this argument. When possible, map large folios in one shot. This reduces the number of minor page faults and allows for TLB coalescing. Mapping large folios at once will allow the rmap code to mlock it on add, as it will recognize that it is fully mapped and mlocking is safe. Signed-off-by: Kiryl Shutsemau --- mm/memory.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/mm/memory.c b/mm/memory.c index 0ba4f6b71847..812a7d9f6531 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -5386,13 +5386,8 @@ vm_fault_t finish_fault(struct vm_fault *vmf) nr_pages = folio_nr_pages(folio); - /* - * Using per-page fault to maintain the uffd semantics, and same - * approach also applies to non shmem/tmpfs faults to avoid - * inflating the RSS of the process. - */ - if (!vma_is_shmem(vma) || unlikely(userfaultfd_armed(vma)) || - unlikely(needs_fallback)) { + /* Using per-page fault to maintain the uffd semantics */ + if (unlikely(userfaultfd_armed(vma)) || unlikely(needs_fallback)) { nr_pages = 1; } else if (nr_pages > 1) { pgoff_t idx = folio_page_idx(folio, page); -- 2.50.1 From: Kiryl Shutsemau The kernel currently does not mlock large folios when adding them to rmap, stating that it is difficult to confirm that the folio is fully mapped and safe to mlock it. However, nowadays the caller passes a number of pages of the folio that are getting mapped, making it easy to check if the entire folio is mapped to the VMA. mlock the folio on rmap if it is fully mapped to the VMA. Signed-off-by: Kiryl Shutsemau --- mm/rmap.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/mm/rmap.c b/mm/rmap.c index 568198e9efc2..ca8d4ef42c2d 100644 --- a/mm/rmap.c +++ b/mm/rmap.c @@ -1478,13 +1478,8 @@ static __always_inline void __folio_add_anon_rmap(struct folio *folio, PageAnonExclusive(cur_page), folio); } - /* - * For large folio, only mlock it if it's fully mapped to VMA. It's - * not easy to check whether the large folio is fully mapped to VMA - * here. Only mlock normal 4K folio and leave page reclaim to handle - * large folio. - */ - if (!folio_test_large(folio)) + /* Only mlock it if the folio is fully mapped to the VMA */ + if (folio_nr_pages(folio) == nr_pages) mlock_vma_folio(folio, vma); } @@ -1620,8 +1615,8 @@ static __always_inline void __folio_add_file_rmap(struct folio *folio, nr = __folio_add_rmap(folio, page, nr_pages, vma, level, &nr_pmdmapped); __folio_mod_stat(folio, nr, nr_pmdmapped); - /* See comments in folio_add_anon_rmap_*() */ - if (!folio_test_large(folio)) + /* Only mlock it if the folio is fully mapped to the VMA */ + if (folio_nr_pages(folio) == nr_pages) mlock_vma_folio(folio, vma); } -- 2.50.1