From e64917250ddb80ff4ab80c0b892eac0152f04d26 Mon Sep 17 00:00:00 2001 From: hanliyang Date: Sat, 11 Jan 2025 15:52:39 +0800 Subject: [PATCH 1/4] Revert "mm/page_alloc: don't use PCP list for THP-sized allocations when using PF_MEMALLOC_PIN" Upstream: no The commit 05848df6e82f ("mm/page_alloc: don't use PCP list for THP-sized allocations when using PF_MEMALLOC_PIN") is a workaround version of the upstream commit bf14ed81f571 ("mm/page_alloc: Separate THP PCP into movable and non-movable categories"). Now, the upstream commit bf14ed81f571 ("mm/page_alloc: Separate THP PCP into movable and non-movable categories") has been backported to the branch linux-6.6/devel of OpenCloudOS-Kernel. Revert the workaround version. Fixes: 05848df6e82f ("mm/page_alloc: don't use PCP list for THP-sized allocations when using PF_MEMALLOC_PIN") Signed-off-by: hanliyang --- mm/page_alloc.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 56db1ea54b5c..5c7df218706d 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -2805,20 +2805,10 @@ struct page *rmqueue(struct zone *preferred_zone, WARN_ON_ONCE((gfp_flags & __GFP_NOFAIL) && (order > 1)); if (likely(pcp_allowed_order(order))) { -#ifdef CONFIG_TRANSPARENT_HUGEPAGE - if (!IS_ENABLED(CONFIG_CMA) || alloc_flags & ALLOC_CMA || - order != pageblock_order) { - page = rmqueue_pcplist(preferred_zone, zone, order, - migratetype, alloc_flags); - if (likely(page)) - goto out; - } -#else page = rmqueue_pcplist(preferred_zone, zone, order, migratetype, alloc_flags); if (likely(page)) goto out; -#endif } page = rmqueue_buddy(preferred_zone, zone, order, alloc_flags, -- Gitee From df0679b619a20788f0e25e7f3167d27a8ea81291 Mon Sep 17 00:00:00 2001 From: yangge Date: Wed, 3 Jul 2024 20:02:33 +0800 Subject: [PATCH 2/4] mm/gup: clear the LRU flag of a page before adding to LRU batch commit 33dfe9204f29b415bbc0abb1a50642d1ba94f5e9 upstream. If a large number of CMA memory are configured in system (for example, the CMA memory accounts for 50% of the system memory), starting a virtual virtual machine with device passthrough, it will call pin_user_pages_remote(..., FOLL_LONGTERM, ...) to pin memory. Normally if a page is present and in CMA area, pin_user_pages_remote() will migrate the page from CMA area to non-CMA area because of FOLL_LONGTERM flag. But the current code will cause the migration failure due to unexpected page refcounts, and eventually cause the virtual machine fail to start. If a page is added in LRU batch, its refcount increases one, remove the page from LRU batch decreases one. Page migration requires the page is not referenced by others except page mapping. Before migrating a page, we should try to drain the page from LRU batch in case the page is in it, however, folio_test_lru() is not sufficient to tell whether the page is in LRU batch or not, if the page is in LRU batch, the migration will fail. To solve the problem above, we modify the logic of adding to LRU batch. Before adding a page to LRU batch, we clear the LRU flag of the page so that we can check whether the page is in LRU batch by folio_test_lru(page). It's quite valuable, because likely we don't want to blindly drain the LRU batch simply because there is some unexpected reference on a page, as described above. This change makes the LRU flag of a page invisible for longer, which may impact some programs. For example, as long as a page is on a LRU batch, we cannot isolate it, and we cannot check if it's an LRU page. Further, a page can now only be on exactly one LRU batch. This doesn't seem to matter much, because a new page is allocated from buddy and added to the lru batch, or be isolated, it's LRU flag may also be invisible for a long time. Link: https://lkml.kernel.org/r/1720075944-27201-1-git-send-email-yangge1116@126.com Link: https://lkml.kernel.org/r/1720008153-16035-1-git-send-email-yangge1116@126.com Fixes: 9a4e9f3b2d73 ("mm: update get_user_pages_longterm to migrate pages allocated from CMA region") Signed-off-by: yangge Cc: Aneesh Kumar K.V Cc: Baolin Wang Cc: David Hildenbrand Cc: Barry Song <21cnbao@gmail.com> Cc: Hugh Dickins Signed-off-by: Andrew Morton --- mm/swap.c | 43 +++++++++++++++++++++++++++++++------------ 1 file changed, 31 insertions(+), 12 deletions(-) diff --git a/mm/swap.c b/mm/swap.c index 14197be6a38a..d4f688424952 100644 --- a/mm/swap.c +++ b/mm/swap.c @@ -201,10 +201,6 @@ static void folio_batch_move_lru(struct folio_batch *fbatch, move_fn_t move_fn) for (i = 0; i < folio_batch_count(fbatch); i++) { struct folio *folio = fbatch->folios[i]; - /* block memcg migration while the folio moves between lru */ - if (move_fn != lru_add_fn && !folio_test_clear_lru(folio)) - continue; - lruvec = folio_lruvec_relock_irqsave(folio, lruvec, &flags); move_fn(lruvec, folio); @@ -246,11 +242,16 @@ static void lru_move_tail_fn(struct lruvec *lruvec, struct folio *folio) void folio_rotate_reclaimable(struct folio *folio) { if (!folio_test_locked(folio) && !folio_test_dirty(folio) && - !folio_test_unevictable(folio) && folio_test_lru(folio)) { + !folio_test_unevictable(folio)) { struct folio_batch *fbatch; unsigned long flags; folio_get(folio); + if (!folio_test_clear_lru(folio)) { + folio_put(folio); + return; + } + local_lock_irqsave(&lru_rotate.lock, flags); fbatch = this_cpu_ptr(&lru_rotate.fbatch); folio_batch_add_and_move(fbatch, folio, lru_move_tail_fn); @@ -343,11 +344,15 @@ static void folio_activate_drain(int cpu) void folio_activate(struct folio *folio) { - if (folio_test_lru(folio) && !folio_test_active(folio) && - !folio_test_unevictable(folio)) { + if (!folio_test_active(folio) && !folio_test_unevictable(folio)) { struct folio_batch *fbatch; folio_get(folio); + if (!folio_test_clear_lru(folio)) { + folio_put(folio); + return; + } + local_lock(&cpu_fbatches.lock); fbatch = this_cpu_ptr(&cpu_fbatches.activate); folio_batch_add_and_move(fbatch, folio, folio_activate_fn); @@ -703,6 +708,11 @@ void deactivate_file_folio(struct folio *folio) return; folio_get(folio); + if (!folio_test_clear_lru(folio)) { + folio_put(folio); + return; + } + local_lock(&cpu_fbatches.lock); fbatch = this_cpu_ptr(&cpu_fbatches.lru_deactivate_file); folio_batch_add_and_move(fbatch, folio, lru_deactivate_file_fn); @@ -719,11 +729,16 @@ void deactivate_file_folio(struct folio *folio) */ void folio_deactivate(struct folio *folio) { - if (folio_test_lru(folio) && !folio_test_unevictable(folio) && - (folio_test_active(folio) || lru_gen_enabled())) { + if (!folio_test_unevictable(folio) && (folio_test_active(folio) || + lru_gen_enabled())) { struct folio_batch *fbatch; folio_get(folio); + if (!folio_test_clear_lru(folio)) { + folio_put(folio); + return; + } + local_lock(&cpu_fbatches.lock); fbatch = this_cpu_ptr(&cpu_fbatches.lru_deactivate); folio_batch_add_and_move(fbatch, folio, lru_deactivate_fn); @@ -740,12 +755,16 @@ void folio_deactivate(struct folio *folio) */ void folio_mark_lazyfree(struct folio *folio) { - if (folio_test_lru(folio) && folio_test_anon(folio) && - folio_test_swapbacked(folio) && !folio_test_swapcache(folio) && - !folio_test_unevictable(folio)) { + if (folio_test_anon(folio) && folio_test_swapbacked(folio) && + !folio_test_swapcache(folio) && !folio_test_unevictable(folio)) { struct folio_batch *fbatch; folio_get(folio); + if (!folio_test_clear_lru(folio)) { + folio_put(folio); + return; + } + local_lock(&cpu_fbatches.lock); fbatch = this_cpu_ptr(&cpu_fbatches.lru_lazyfree); folio_batch_add_and_move(fbatch, folio, lru_lazyfree_fn); -- Gitee From e860fa7cc3842011dd2200087ab9727714d77aab Mon Sep 17 00:00:00 2001 From: Chris Li Date: Thu, 5 Sep 2024 01:08:17 -0700 Subject: [PATCH 3/4] mm: vmscan.c: fix OOM on swap stress test commit 0885ef4705607936fc36a38fd74356e1c465b023 upstream. I found a regression on mm-unstable during my swap stress test, using tmpfs to compile linux. The test OOM very soon after the make spawns many cc processes. It bisects down to this change: 33dfe9204f29b415bbc0abb1a50642d1ba94f5e9 (mm/gup: clear the LRU flag of a page before adding to LRU batch) Yu Zhao propose the fix: "I think this is one of the potential side effects -- Huge mentioned earlier about isolate_lru_folios():" I test that with it the swap stress test no longer OOM. Link: https://lore.kernel.org/r/CAOUHufYi9h0kz5uW3LHHS3ZrVwEq-kKp8S6N-MZUmErNAXoXmw@mail.gmail.com/ Link: https://lkml.kernel.org/r/20240905-lru-flag-v2-1-8a2d9046c594@kernel.org Fixes: 33dfe9204f29 ("mm/gup: clear the LRU flag of a page before adding to LRU batch") Signed-off-by: Chris Li Suggested-by: Yu Zhao Suggested-by: Hugh Dickins Closes: https://lore.kernel.org/all/CAF8kJuNP5iTj2p07QgHSGOJsiUfYpJ2f4R1Q5-3BN9JiD9W_KA@mail.gmail.com/ Signed-off-by: Andrew Morton --- mm/vmscan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mm/vmscan.c b/mm/vmscan.c index 93b8b7010082..6f54f530dffb 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -5116,7 +5116,7 @@ static bool sort_folio(struct lruvec *lruvec, struct folio *folio, struct scan_c } /* ineligible */ - if (zone > sc->reclaim_idx) { + if (!folio_test_lru(folio) || zone > sc->reclaim_idx) { gen = folio_inc_gen(lruvec, folio, false); list_move_tail(&folio->lru, &lrugen->folios[gen][type][zone]); return true; -- Gitee From 531f9a2515a9070a087ba96926f72172f131f1f0 Mon Sep 17 00:00:00 2001 From: hanliyang Date: Sun, 12 Jan 2025 17:21:08 +0800 Subject: [PATCH 4/4] Revert "mm/gup: don't check if a page is in lru before draining it" Upstream: no The commit 11d27a0ed539 ("mm/gup: don't check if a page is in lru before draining it") is a workaround version of the upstream commit 33dfe9204f29 ("mm/gup: clear the LRU flag of a page before adding to LRU batch"). We have backported the upstream version to the branch linux-6.6/devel of OpenCloudOS-Kernel. Revert the workaround version. Fixes: 11d27a0ed539 ("mm/gup: don't check if a page is in lru before draining it") Signed-off-by: hanliyang --- mm/gup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mm/gup.c b/mm/gup.c index 2576962d4538..fdd75384160d 100644 --- a/mm/gup.c +++ b/mm/gup.c @@ -1975,7 +1975,7 @@ static unsigned long collect_longterm_unpinnable_pages( continue; } - if (drain_allow) { + if (!folio_test_lru(folio) && drain_allow) { lru_add_drain_all(); drain_allow = false; } -- Gitee