Skip to content

Commit 47932e7

Browse files
Matthew Wilcox (Oracle)akpm00
authored andcommitted
mm: remove folio from deferred split list before uncharging it
When freeing a large folio, we must remove it from the deferred split list before we uncharge it as each memcg has its own deferred split list (with associated lock) and removing a folio from the deferred split list while holding the wrong lock will corrupt that list and cause various related problems. Link: https://lore.kernel.org/linux-mm/[email protected]/ Link: https://lkml.kernel.org/r/[email protected] Fixes: f77171d (mm: allow non-hugetlb large folios to be batch processed) Fixes: 29f3843 (mm: free folios directly in move_folios_to_lru()) Fixes: bc2ff4c (mm: free folios in a batch in shrink_folio_list()) Signed-off-by: Matthew Wilcox (Oracle) <[email protected]> Debugged-by: Ryan Roberts <[email protected]> Tested-by: Ryan Roberts <[email protected]> Signed-off-by: Andrew Morton <[email protected]>
1 parent 58f327f commit 47932e7

File tree

2 files changed

+9
-0
lines changed

2 files changed

+9
-0
lines changed

mm/swap.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1012,6 +1012,9 @@ void folios_put_refs(struct folio_batch *folios, unsigned int *refs)
10121012
free_huge_folio(folio);
10131013
continue;
10141014
}
1015+
if (folio_test_large(folio) &&
1016+
folio_test_large_rmappable(folio))
1017+
folio_undo_large_rmappable(folio);
10151018

10161019
__page_cache_release(folio, &lruvec, &flags);
10171020

mm/vmscan.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1413,6 +1413,9 @@ static unsigned int shrink_folio_list(struct list_head *folio_list,
14131413
*/
14141414
nr_reclaimed += nr_pages;
14151415

1416+
if (folio_test_large(folio) &&
1417+
folio_test_large_rmappable(folio))
1418+
folio_undo_large_rmappable(folio);
14161419
if (folio_batch_add(&free_folios, folio) == 0) {
14171420
mem_cgroup_uncharge_folios(&free_folios);
14181421
try_to_unmap_flush();
@@ -1819,6 +1822,9 @@ static unsigned int move_folios_to_lru(struct lruvec *lruvec,
18191822
if (unlikely(folio_put_testzero(folio))) {
18201823
__folio_clear_lru_flags(folio);
18211824

1825+
if (folio_test_large(folio) &&
1826+
folio_test_large_rmappable(folio))
1827+
folio_undo_large_rmappable(folio);
18221828
if (folio_batch_add(&free_folios, folio) == 0) {
18231829
spin_unlock_irq(&lruvec->lru_lock);
18241830
mem_cgroup_uncharge_folios(&free_folios);

0 commit comments

Comments
 (0)