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/rmap: do __folio_mod_stat() in __folio_add_rmap()

It is required to modify folio statistic after rmap changes, so it looks
reasonable to do it in __folio_add_rmap(), which is the current behavior
of __folio_remove_rmap() and folio_add_new_anon_rmap().

Call __folio_mod_stat() in __folio_add_rmap(), so that rmap adjustment
family shares the same pattern.

Link: https://lkml.kernel.org/r/20250804064106.21269-1-richard.weiyang@gmail.com
Signed-off-by: Wei Yang <richard.weiyang@gmail.com>
Acked-by: David Hildenbrand <david@redhat.com>
Reviewed-by: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
Cc: Rik van Riel <riel@surriel.com>
Cc: Liam R. Howlett <Liam.Howlett@oracle.com>
Cc: Vlastimil Babka <vbabka@suse.cz>
Cc: Harry Yoo <harry.yoo@oracle.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

authored by

Wei Yang and committed by
Andrew Morton
878d9e8c 9863124e

+31 -36
+31 -36
mm/rmap.c
··· 1241 1241 return page_vma_mkclean_one(&pvmw); 1242 1242 } 1243 1243 1244 - static __always_inline unsigned int __folio_add_rmap(struct folio *folio, 1244 + static void __folio_mod_stat(struct folio *folio, int nr, int nr_pmdmapped) 1245 + { 1246 + int idx; 1247 + 1248 + if (nr) { 1249 + idx = folio_test_anon(folio) ? NR_ANON_MAPPED : NR_FILE_MAPPED; 1250 + __lruvec_stat_mod_folio(folio, idx, nr); 1251 + } 1252 + if (nr_pmdmapped) { 1253 + if (folio_test_anon(folio)) { 1254 + idx = NR_ANON_THPS; 1255 + __lruvec_stat_mod_folio(folio, idx, nr_pmdmapped); 1256 + } else { 1257 + /* NR_*_PMDMAPPED are not maintained per-memcg */ 1258 + idx = folio_test_swapbacked(folio) ? 1259 + NR_SHMEM_PMDMAPPED : NR_FILE_PMDMAPPED; 1260 + __mod_node_page_state(folio_pgdat(folio), idx, 1261 + nr_pmdmapped); 1262 + } 1263 + } 1264 + } 1265 + 1266 + static __always_inline void __folio_add_rmap(struct folio *folio, 1245 1267 struct page *page, int nr_pages, struct vm_area_struct *vma, 1246 - enum rmap_level level, int *nr_pmdmapped) 1268 + enum rmap_level level) 1247 1269 { 1248 1270 atomic_t *mapped = &folio->_nr_pages_mapped; 1249 1271 const int orig_nr_pages = nr_pages; 1250 - int first = 0, nr = 0; 1272 + int first = 0, nr = 0, nr_pmdmapped = 0; 1251 1273 1252 1274 __folio_rmap_sanity_checks(folio, page, nr_pages, level); 1253 1275 ··· 1305 1283 first = atomic_inc_and_test(&folio->_entire_mapcount); 1306 1284 if (IS_ENABLED(CONFIG_NO_PAGE_MAPCOUNT)) { 1307 1285 if (level == RMAP_LEVEL_PMD && first) 1308 - *nr_pmdmapped = folio_large_nr_pages(folio); 1286 + nr_pmdmapped = folio_large_nr_pages(folio); 1309 1287 nr = folio_inc_return_large_mapcount(folio, vma); 1310 1288 if (nr == 1) 1311 1289 /* Was completely unmapped. */ ··· 1324 1302 * folios separately. 1325 1303 */ 1326 1304 if (level == RMAP_LEVEL_PMD) 1327 - *nr_pmdmapped = nr_pages; 1305 + nr_pmdmapped = nr_pages; 1328 1306 nr = nr_pages - (nr & FOLIO_PAGES_MAPPED); 1329 1307 /* Raced ahead of a remove and another add? */ 1330 1308 if (unlikely(nr < 0)) ··· 1337 1315 folio_inc_large_mapcount(folio, vma); 1338 1316 break; 1339 1317 } 1340 - return nr; 1318 + __folio_mod_stat(folio, nr, nr_pmdmapped); 1341 1319 } 1342 1320 1343 1321 /** ··· 1425 1403 page); 1426 1404 } 1427 1405 1428 - static void __folio_mod_stat(struct folio *folio, int nr, int nr_pmdmapped) 1429 - { 1430 - int idx; 1431 - 1432 - if (nr) { 1433 - idx = folio_test_anon(folio) ? NR_ANON_MAPPED : NR_FILE_MAPPED; 1434 - __lruvec_stat_mod_folio(folio, idx, nr); 1435 - } 1436 - if (nr_pmdmapped) { 1437 - if (folio_test_anon(folio)) { 1438 - idx = NR_ANON_THPS; 1439 - __lruvec_stat_mod_folio(folio, idx, nr_pmdmapped); 1440 - } else { 1441 - /* NR_*_PMDMAPPED are not maintained per-memcg */ 1442 - idx = folio_test_swapbacked(folio) ? 1443 - NR_SHMEM_PMDMAPPED : NR_FILE_PMDMAPPED; 1444 - __mod_node_page_state(folio_pgdat(folio), idx, 1445 - nr_pmdmapped); 1446 - } 1447 - } 1448 - } 1449 - 1450 1406 static __always_inline void __folio_add_anon_rmap(struct folio *folio, 1451 1407 struct page *page, int nr_pages, struct vm_area_struct *vma, 1452 1408 unsigned long address, rmap_t flags, enum rmap_level level) 1453 1409 { 1454 - int i, nr, nr_pmdmapped = 0; 1410 + int i; 1455 1411 1456 1412 VM_WARN_ON_FOLIO(!folio_test_anon(folio), folio); 1457 1413 1458 - nr = __folio_add_rmap(folio, page, nr_pages, vma, level, &nr_pmdmapped); 1414 + __folio_add_rmap(folio, page, nr_pages, vma, level); 1459 1415 1460 1416 if (likely(!folio_test_ksm(folio))) 1461 1417 __page_check_anon_rmap(folio, page, vma, address); 1462 - 1463 - __folio_mod_stat(folio, nr, nr_pmdmapped); 1464 1418 1465 1419 if (flags & RMAP_EXCLUSIVE) { 1466 1420 switch (level) { ··· 1611 1613 struct page *page, int nr_pages, struct vm_area_struct *vma, 1612 1614 enum rmap_level level) 1613 1615 { 1614 - int nr, nr_pmdmapped = 0; 1615 - 1616 1616 VM_WARN_ON_FOLIO(folio_test_anon(folio), folio); 1617 1617 1618 - nr = __folio_add_rmap(folio, page, nr_pages, vma, level, &nr_pmdmapped); 1619 - __folio_mod_stat(folio, nr, nr_pmdmapped); 1618 + __folio_add_rmap(folio, page, nr_pages, vma, level); 1620 1619 1621 1620 /* See comments in folio_add_anon_rmap_*() */ 1622 1621 if (!folio_test_large(folio))