Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

mm/mincore, swap: consolidate swap cache checking for mincore

Patch series "mm/mincore: minor clean up for swap cache checking".

This series cleans up a swap cache helper only used by mincore, move it
back into mincore code. Also separate the swap cache related logics out
of shmem / page cache logics in mincore.

With this series we have less lines of code and better performance.

Before this series:
mincore on a swaped out 16G anon mmap range:
Took 488220 us
mincore on 16G shmem mmap range:
Took 530272 us.

After this series:
mincore on a swaped out 16G anon mmap range:
Took 446763 us
mincore on 16G shmem mmap range:
Took 460496 us.

About ~10% faster.


This patch (of 2):

The filemap_get_incore_folio (previously find_get_incore_page) helper was
introduced by commit 61ef18655704 ("mm: factor find_get_incore_page out of
mincore_page") to be used by later commit f5df8635c5a3 ("mm: use
find_get_incore_page in memcontrol"), so memory cgroup charge move code
can be simplified.

But commit 6b611388b626 ("memcg-v1: remove charge move code") removed that
user completely, it's only used by mincore now.

So this commit basically reverts commit 61ef18655704 ("mm: factor
find_get_incore_page out of mincore_page"). Move it back to mincore side
to simplify the code.

Link: https://lkml.kernel.org/r/20250811172018.48901-1-ryncsn@gmail.com
Link: https://lkml.kernel.org/r/20250811172018.48901-2-ryncsn@gmail.com
Signed-off-by: Kairui Song <kasong@tencent.com>
Acked-by: Nhat Pham <nphamcs@gmail.com>
Cc: Baoquan He <bhe@redhat.com>
Cc: Barry Song <baohua@kernel.org>
Cc: Chris Li <chrisl@kernel.org>
Cc: David Hildenbrand <david@redhat.com>
Cc: Hugh Dickins <hughd@google.com>
Cc: Jann Horn <jannh@google.com>
Cc: Kemeng Shi <shikemeng@huaweicloud.com>
Cc: Liam Howlett <liam.howlett@oracle.com>
Cc: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
Cc: Matthew Wilcox (Oracle) <willy@infradead.org>
Cc: Vlastimil Babka <vbabka@suse.cz>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

authored by

Kairui Song and committed by
Andrew Morton
27763eda 7bca1760

+27 -50
+27 -2
mm/mincore.c
··· 64 64 * any other file mapping (ie. marked !present and faulted in with 65 65 * tmpfs's .fault). So swapped out tmpfs mappings are tested here. 66 66 */ 67 - folio = filemap_get_incore_folio(mapping, index); 68 - if (!IS_ERR(folio)) { 67 + if (IS_ENABLED(CONFIG_SWAP) && shmem_mapping(mapping)) { 68 + folio = filemap_get_entry(mapping, index); 69 + /* 70 + * shmem/tmpfs may return swap: account for swapcache 71 + * page too. 72 + */ 73 + if (xa_is_value(folio)) { 74 + struct swap_info_struct *si; 75 + swp_entry_t swp = radix_to_swp_entry(folio); 76 + /* There might be swapin error entries in shmem mapping. */ 77 + if (non_swap_entry(swp)) 78 + return 0; 79 + /* Prevent swap device to being swapoff under us */ 80 + si = get_swap_device(swp); 81 + if (si) { 82 + folio = filemap_get_folio(swap_address_space(swp), 83 + swap_cache_index(swp)); 84 + put_swap_device(si); 85 + } else { 86 + return 0; 87 + } 88 + } 89 + } else { 90 + folio = filemap_get_folio(mapping, index); 91 + } 92 + 93 + if (!IS_ERR_OR_NULL(folio)) { 69 94 present = folio_test_uptodate(folio); 70 95 folio_put(folio); 71 96 }
-10
mm/swap.h
··· 64 64 void swapcache_clear(struct swap_info_struct *si, swp_entry_t entry, int nr); 65 65 struct folio *swap_cache_get_folio(swp_entry_t entry, 66 66 struct vm_area_struct *vma, unsigned long addr); 67 - struct folio *filemap_get_incore_folio(struct address_space *mapping, 68 - pgoff_t index); 69 - 70 67 struct folio *read_swap_cache_async(swp_entry_t entry, gfp_t gfp_mask, 71 68 struct vm_area_struct *vma, unsigned long addr, 72 69 struct swap_iocb **plug); ··· 173 176 struct vm_area_struct *vma, unsigned long addr) 174 177 { 175 178 return NULL; 176 - } 177 - 178 - static inline 179 - struct folio *filemap_get_incore_folio(struct address_space *mapping, 180 - pgoff_t index) 181 - { 182 - return filemap_get_folio(mapping, index); 183 179 } 184 180 185 181 static inline void *get_shadow_from_swap_cache(swp_entry_t entry)
-38
mm/swap_state.c
··· 323 323 return folio; 324 324 } 325 325 326 - /** 327 - * filemap_get_incore_folio - Find and get a folio from the page or swap caches. 328 - * @mapping: The address_space to search. 329 - * @index: The page cache index. 330 - * 331 - * This differs from filemap_get_folio() in that it will also look for the 332 - * folio in the swap cache. 333 - * 334 - * Return: The found folio or %NULL. 335 - */ 336 - struct folio *filemap_get_incore_folio(struct address_space *mapping, 337 - pgoff_t index) 338 - { 339 - swp_entry_t swp; 340 - struct swap_info_struct *si; 341 - struct folio *folio = filemap_get_entry(mapping, index); 342 - 343 - if (!folio) 344 - return ERR_PTR(-ENOENT); 345 - if (!xa_is_value(folio)) 346 - return folio; 347 - if (!shmem_mapping(mapping)) 348 - return ERR_PTR(-ENOENT); 349 - 350 - swp = radix_to_swp_entry(folio); 351 - /* There might be swapin error entries in shmem mapping. */ 352 - if (non_swap_entry(swp)) 353 - return ERR_PTR(-ENOENT); 354 - /* Prevent swapoff from happening to us */ 355 - si = get_swap_device(swp); 356 - if (!si) 357 - return ERR_PTR(-ENOENT); 358 - index = swap_cache_index(swp); 359 - folio = filemap_get_folio(swap_address_space(swp), index); 360 - put_swap_device(si); 361 - return folio; 362 - } 363 - 364 326 struct folio *__read_swap_cache_async(swp_entry_t entry, gfp_t gfp_mask, 365 327 struct mempolicy *mpol, pgoff_t ilx, bool *new_page_allocated, 366 328 bool skip_if_exists)