FAILED: patch "[PATCH] mm: folio_may_be_lru_cached() unless folio_test_large()" failed to apply to 6.12-stable tree
Subsystems (5)
[email protected]
maintainerThe patch below does not apply to the 6.12-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-6.12.y
git checkout FETCH_HEAD
git cherry-pick -x 2da6de30e60dd9bb14600eff1cc99df2fa2ddae3
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2025092142-easiness-blatancy-23af@gregkh' --subject-prefix 'PATCH 6.12.y' HEAD^..
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 2da6de30e60dd9bb14600eff1cc99df2fa2ddae3 Mon Sep 17 00:00:00 2001
From: Hugh Dickins <[email protected]>
Date: Mon, 8 Sep 2025 15:23:15 -0700
Subject: [PATCH] mm: folio_may_be_lru_cached() unless folio_test_large()
mm/swap.c and mm/mlock.c agree to drain any per-CPU batch as soon as a large folio is added: so collect_longterm_unpinnable_folios() just wastes effort when calling lru_add_drain[_all]() on a large folio.
But although there is good reason not to batch up PMD-sized folios, we might well benefit from batching a small number of low-order mTHPs (though unclear how that "small number" limitation will be implemented).
So ask if folio_may_be_lru_cached() rather than !folio_test_large(), to insulate those particular checks from future change. Name preferred to "folio_is_batchable" because large folios can well be put on a batch: it's just the per-CPU LRU caches, drained much later, which need care.
Marked for stable, to counter the increase in lru_add_drain_all()s from "mm/gup: check ref_count instead of lru before migration".
include/linux/swap.h +10 -0
@@ -385,6 +385,16 @@ void folio_add_lru_vma(struct folio *, struct vm_area_struct *);void mark_page_accessed (struct page *);void folio_mark_accessed (struct folio *); +static inline bool folio_may_be_lru_cached (struct folio *folio) +{ +/* +* Holding PMD-sized folios in per-CPU LRU cache unbalances accounting. +* Holding small numbers of low-order mTHP folios in per-CPU LRU cache +* will be sensible, but nobody has implemented and tested that yet. +*/ +return !folio_test_large (folio); +} +extern atomic_t lru_disable_count;static inline bool lru_cache_disabled (void )
mm/gup.c +2 -2
@@ -2307,13 +2307,13 @@ static unsigned long collect_longterm_unpinnable_folios(continue ; } -if (drained ==0 && +if (drained ==0 &&folio_may_be_lru_cached (folio) &&folio_ref_count (folio) !=folio_expected_ref_count (folio) +1 ) {lru_add_drain (); drained =1 ; } -if (drained ==1 && +if (drained ==1 &&folio_may_be_lru_cached (folio) &&folio_ref_count (folio) !=folio_expected_ref_count (folio) +1 ) {lru_add_drain_all ();
mm/mlock.c +3 -3
@@ -255,7 +255,7 @@ void mlock_folio(struct folio *folio)folio_get (folio);if (!folio_batch_add (fbatch,mlock_lru (folio)) || -folio_test_large (folio) ||lru_cache_disabled ()) + !folio_may_be_lru_cached (folio) ||lru_cache_disabled ())mlock_folio_batch (fbatch);local_unlock (&mlock_fbatch.lock); }
@@ -278,7 +278,7 @@ void mlock_new_folio(struct folio *folio)folio_get (folio);if (!folio_batch_add (fbatch,mlock_new (folio)) || -folio_test_large (folio) ||lru_cache_disabled ()) + !folio_may_be_lru_cached (folio) ||lru_cache_disabled ())mlock_folio_batch (fbatch);local_unlock (&mlock_fbatch.lock); }
@@ -299,7 +299,7 @@ void munlock_folio(struct folio *folio)*/ folio_get (folio);if (!folio_batch_add (fbatch, folio) || -folio_test_large (folio) ||lru_cache_disabled ()) + !folio_may_be_lru_cached (folio) ||lru_cache_disabled ())mlock_folio_batch (fbatch);local_unlock (&mlock_fbatch.lock); }
mm/swap.c +1 -1
@@ -192,7 +192,7 @@ static void __folio_batch_add_and_move(struct folio_batch __percpu *fbatch,local_lock (&cpu_fbatches.lock);if (!folio_batch_add (this_cpu_ptr (fbatch), folio) || -folio_test_large (folio) ||lru_cache_disabled ()) + !folio_may_be_lru_cached (folio) ||lru_cache_disabled ())folio_batch_move_lru (this_cpu_ptr (fbatch), move_fn);if (disable_irq)
Sasha Levin
maintainerPATCH 1/1 mm: folio_may_be_lru_cached() unless folio_test_large()
From: Hugh Dickins <[email protected]>
[ Upstream commit 2da6de30e60dd9bb14600eff1cc99df2fa2ddae3 ]
mm/swap.c and mm/mlock.c agree to drain any per-CPU batch as soon as a large folio is added: so collect_longterm_unpinnable_folios() just wastes effort when calling lru_add_drain[_all]() on a large folio.
But although there is good reason not to batch up PMD-sized folios, we might well benefit from batching a small number of low-order mTHPs (though unclear how that "small number" limitation will be implemented).
So ask if folio_may_be_lru_cached() rather than !folio_test_large(), to insulate those particular checks from future change. Name preferred to "folio_is_batchable" because large folios can well be put on a batch: it's just the per-CPU LRU caches, drained much later, which need care.
Marked for stable, to counter the increase in lru_add_drain_all()s from "mm/gup: check ref_count instead of lru before migration".
--- include/linux/swap.h | 10 ++++++++++ mm/gup.c | 3 ++- mm/mlock.c | 6 +++--- mm/swap.c | 4 ++-- 4 files changed, 17 insertions(+), 6 deletions(-)
include/linux/swap.h +10 -0
@@ -382,6 +382,16 @@ void folio_add_lru_vma(struct folio *, struct vm_area_struct *);void mark_page_accessed (struct page *);void folio_mark_accessed (struct folio *); +static inline bool folio_may_be_lru_cached (struct folio *folio) +{ +/* +* Holding PMD-sized folios in per-CPU LRU cache unbalances accounting. +* Holding small numbers of low-order mTHP folios in per-CPU LRU cache +* will be sensible, but nobody has implemented and tested that yet. +*/ +return !folio_test_large (folio); +} +extern atomic_t lru_disable_count;static inline bool lru_cache_disabled (void )
mm/gup.c +2 -1
@@ -2354,7 +2354,8 @@ static unsigned long collect_longterm_unpinnable_folios(continue ; } -if (!folio_test_lru (folio) && drain_allow) { +if (!folio_test_lru (folio) &&folio_may_be_lru_cached (folio) && + drain_allow) {lru_add_drain_all (); drain_allow = false; }
mm/mlock.c +3 -3
@@ -255,7 +255,7 @@ void mlock_folio(struct folio *folio)folio_get (folio);if (!folio_batch_add (fbatch,mlock_lru (folio)) || -folio_test_large (folio) ||lru_cache_disabled ()) + !folio_may_be_lru_cached (folio) ||lru_cache_disabled ())mlock_folio_batch (fbatch);local_unlock (&mlock_fbatch.lock); }
@@ -278,7 +278,7 @@ void mlock_new_folio(struct folio *folio)folio_get (folio);if (!folio_batch_add (fbatch,mlock_new (folio)) || -folio_test_large (folio) ||lru_cache_disabled ()) + !folio_may_be_lru_cached (folio) ||lru_cache_disabled ())mlock_folio_batch (fbatch);local_unlock (&mlock_fbatch.lock); }
@@ -299,7 +299,7 @@ void munlock_folio(struct folio *folio)*/ folio_get (folio);if (!folio_batch_add (fbatch, folio) || -folio_test_large (folio) ||lru_cache_disabled ()) + !folio_may_be_lru_cached (folio) ||lru_cache_disabled ())mlock_folio_batch (fbatch);local_unlock (&mlock_fbatch.lock); }
mm/swap.c +2 -2
@@ -222,8 +222,8 @@ static void __folio_batch_add_and_move(struct folio_batch __percpu *fbatch,else local_lock (&cpu_fbatches.lock); -if (!folio_batch_add (this_cpu_ptr (fbatch), folio) ||folio_test_large (folio) || -lru_cache_disabled ()) +if (!folio_batch_add (this_cpu_ptr (fbatch), folio) || + !folio_may_be_lru_cached (folio) ||lru_cache_disabled ())folio_batch_move_lru (this_cpu_ptr (fbatch), move_fn);if (disable_irq)
Signature · 1 line
2.51.0
Greg KH
maintainerRe: [PATCH 6.12.y] mm: folio_may_be_lru_cached() unless folio_test_large()
Quoted 49 lines · Sasha Levin
From: Hugh Dickins <[email protected]>
[ Upstream commit
2da6de30e60dd9bb14600eff1cc99df2fa2ddae3]
mm/swap.candmm/mlock.cagree to drain any per-CPU batch as soon as a large folio is added: socollect_longterm_unpinnable_folios()just wastes effort when calling lru_add_drain[_all]() on a large folio.But although there is good reason not to batch up PMD-sized folios, we might well benefit from batching a small number of low-order mTHPs (though unclear how that "small number" limitation will be implemented).
So ask if
folio_may_be_lru_cached()rather than !folio_test_large(), to insulate those particular checks from future change. Name preferred to "folio_is_batchable" because large folios can well be put on a batch: it's just the per-CPU LRU caches, drained much later, which need care.Marked for stable, to counter the increase in lru_add_drain_all()s from "mm/gup: check
ref_countinstead of lru before migration".Fixes 9a4e9f3b2d73 ("mm: update get_user_pages_longterm to migrate pages allocated from CMA region")Signed-off-by Hugh Dickins <[email protected]>Suggested-by David Hildenbrand <[email protected]>Cc "Aneesh Kumar K.V" <[email protected]>Cc Axel Rasmussen <[email protected]>Cc Chris Li <[email protected]>Cc Christoph Hellwig <[email protected]>Cc Jason Gunthorpe <[email protected]>Cc Johannes Weiner <[email protected]>Cc John Hubbard <[email protected]>Cc Keir Fraser <[email protected]>Cc Konstantin Khlebnikov <[email protected]>Cc Li Zhe <[email protected]>Cc Matthew Wilcox (Oracle) <[email protected]>Cc Peter Xu <[email protected]>Cc Rik van Riel <[email protected]>Cc Shivank Garg <[email protected]>Cc Vlastimil Babka <[email protected]>Cc Wei Xu <[email protected]>Cc Will Deacon <[email protected]>Cc yangge <[email protected]>Cc Yuanchu Xie <[email protected]>Cc Yu Zhao <[email protected]>Cc <[email protected]>Signed-off-by Andrew Morton <[email protected]>[ adapted to drain_allow instead of drained ]Signed-off-by Sasha Levin <[email protected]>
Quoted 1 line
---
Does not apply as it conflicts with the other mm changes you sent right before this one :(
Re: [PATCH 6.12.y] mm: folio_may_be_lru_cached() unless folio_test_large()
Quoted 52 lines · Greg KH
Quoted 49 lines · Sasha Levin
From: Hugh Dickins <[email protected]>
[ Upstream commit
2da6de30e60dd9bb14600eff1cc99df2fa2ddae3]
mm/swap.candmm/mlock.cagree to drain any per-CPU batch as soon as a large folio is added: socollect_longterm_unpinnable_folios()just wastes effort when calling lru_add_drain[_all]() on a large folio.But although there is good reason not to batch up PMD-sized folios, we might well benefit from batching a small number of low-order mTHPs (though unclear how that "small number" limitation will be implemented).
So ask if
folio_may_be_lru_cached()rather than !folio_test_large(), to insulate those particular checks from future change. Name preferred to "folio_is_batchable" because large folios can well be put on a batch: it's just the per-CPU LRU caches, drained much later, which need care.Marked for stable, to counter the increase in lru_add_drain_all()s from "mm/gup: check
ref_countinstead of lru before migration".Fixes 9a4e9f3b2d73 ("mm: update get_user_pages_longterm to migrate pages allocated from CMA region")Signed-off-by Hugh Dickins <[email protected]>Suggested-by David Hildenbrand <[email protected]>Cc "Aneesh Kumar K.V" <[email protected]>Cc Axel Rasmussen <[email protected]>Cc Chris Li <[email protected]>Cc Christoph Hellwig <[email protected]>Cc Jason Gunthorpe <[email protected]>Cc Johannes Weiner <[email protected]>Cc John Hubbard <[email protected]>Cc Keir Fraser <[email protected]>Cc Konstantin Khlebnikov <[email protected]>Cc Li Zhe <[email protected]>Cc Matthew Wilcox (Oracle) <[email protected]>Cc Peter Xu <[email protected]>Cc Rik van Riel <[email protected]>Cc Shivank Garg <[email protected]>Cc Vlastimil Babka <[email protected]>Cc Wei Xu <[email protected]>Cc Will Deacon <[email protected]>Cc yangge <[email protected]>Cc Yuanchu Xie <[email protected]>Cc Yu Zhao <[email protected]>Cc <[email protected]>Signed-off-by Andrew Morton <[email protected]>[ adapted to drain_allow instead of drained ]Signed-off-by Sasha Levin <[email protected]>Quoted 1 line
---
Quoted 2 lines
Does not apply as it conflicts with the other mm changes you sent right before this one :(
Thanks for grabbing all these, I'm sorry they are troublesome.
Though I'm usually able to work out what to do from the FAILED mails, in this case I'd just be guessing without the full contexts. So I'll wait until I see what goes into the various branches of linux-stable-rc.git before checking and adjusting where necessary.
(As usual, I'll tend towards minimal change, where Sasha tends towards maximal backporting of encroaching mods: we may disagree.)
The main commits contributing to the pinning failures that Will Deacon reported were commits going into 5.18 and 6.11. So although I stand by my Fixes tag, I'm likely to conclude that 5.15 and 5.10 and 5.4 are better left stable without any of it.
Thanks,
Hugh
Re: [PATCH 6.12.y] mm: folio_may_be_lru_cached() unless folio_test_large()
Quoted 63 lines · Hugh Dickins
Quoted 52 lines · Greg KH
Quoted 49 lines · Sasha Levin
From: Hugh Dickins <[email protected]>
[ Upstream commit
2da6de30e60dd9bb14600eff1cc99df2fa2ddae3]
mm/swap.candmm/mlock.cagree to drain any per-CPU batch as soon as a large folio is added: socollect_longterm_unpinnable_folios()just wastes effort when calling lru_add_drain[_all]() on a large folio.But although there is good reason not to batch up PMD-sized folios, we might well benefit from batching a small number of low-order mTHPs (though unclear how that "small number" limitation will be implemented).
So ask if
folio_may_be_lru_cached()rather than !folio_test_large(), to insulate those particular checks from future change. Name preferred to "folio_is_batchable" because large folios can well be put on a batch: it's just the per-CPU LRU caches, drained much later, which need care.Marked for stable, to counter the increase in lru_add_drain_all()s from "mm/gup: check
ref_countinstead of lru before migration".Fixes 9a4e9f3b2d73 ("mm: update get_user_pages_longterm to migrate pages allocated from CMA region")Signed-off-by Hugh Dickins <[email protected]>Suggested-by David Hildenbrand <[email protected]>Cc "Aneesh Kumar K.V" <[email protected]>Cc Axel Rasmussen <[email protected]>Cc Chris Li <[email protected]>Cc Christoph Hellwig <[email protected]>Cc Jason Gunthorpe <[email protected]>Cc Johannes Weiner <[email protected]>Cc John Hubbard <[email protected]>Cc Keir Fraser <[email protected]>Cc Konstantin Khlebnikov <[email protected]>Cc Li Zhe <[email protected]>Cc Matthew Wilcox (Oracle) <[email protected]>Cc Peter Xu <[email protected]>Cc Rik van Riel <[email protected]>Cc Shivank Garg <[email protected]>Cc Vlastimil Babka <[email protected]>Cc Wei Xu <[email protected]>Cc Will Deacon <[email protected]>Cc yangge <[email protected]>Cc Yuanchu Xie <[email protected]>Cc Yu Zhao <[email protected]>Cc <[email protected]>Signed-off-by Andrew Morton <[email protected]>[ adapted to drain_allow instead of drained ]Signed-off-by Sasha Levin <[email protected]>Quoted 1 line
---
Quoted 2 lines
Does not apply as it conflicts with the other mm changes you sent right before this one :(
Thanks for grabbing all these, I'm sorry they are troublesome.
Though I'm usually able to work out what to do from the FAILED mails, in this case I'd just be guessing without the full contexts. So I'll wait until I see what goes into the various branches of linux-stable-rc.git before checking and adjusting where necessary.
Quoted 7 lines
(As usual, I'll tend towards minimal change, where Sasha tends towards maximal backporting of encroaching mods: we may disagree.)
The main commits contributing to the pinning failures that Will Deacon reported were commits going into 5.18 and 6.11. So although I stand by my Fixes tag, I'm likely to conclude that 5.15 and 5.10 and 5.4 are better left stable without any of it.
That suits me. 6.1, 6.6 and 6.12 are the main ones that I'm concerned with from the Android side.
Will
Sasha Levin
maintainerRe: [PATCH 6.12.y] mm: folio_may_be_lru_cached() unless folio_test_large()
Quoted 67 lines · Will Deacon
Quoted 66 lines · Hugh Dickins
Quoted 52 lines · Greg KH
Quoted 49 lines · Sasha Levin
From: Hugh Dickins <[email protected]>
[ Upstream commit
2da6de30e60dd9bb14600eff1cc99df2fa2ddae3]
mm/swap.candmm/mlock.cagree to drain any per-CPU batch as soon as a large folio is added: socollect_longterm_unpinnable_folios()just wastes effort when calling lru_add_drain[_all]() on a large folio.But although there is good reason not to batch up PMD-sized folios, we might well benefit from batching a small number of low-order mTHPs (though unclear how that "small number" limitation will be implemented).
So ask if
folio_may_be_lru_cached()rather than !folio_test_large(), to insulate those particular checks from future change. Name preferred to "folio_is_batchable" because large folios can well be put on a batch: it's just the per-CPU LRU caches, drained much later, which need care.Marked for stable, to counter the increase in lru_add_drain_all()s from "mm/gup: check
ref_countinstead of lru before migration".Fixes 9a4e9f3b2d73 ("mm: update get_user_pages_longterm to migrate pages allocated from CMA region")Signed-off-by Hugh Dickins <[email protected]>Suggested-by David Hildenbrand <[email protected]>Cc "Aneesh Kumar K.V" <[email protected]>Cc Axel Rasmussen <[email protected]>Cc Chris Li <[email protected]>Cc Christoph Hellwig <[email protected]>Cc Jason Gunthorpe <[email protected]>Cc Johannes Weiner <[email protected]>Cc John Hubbard <[email protected]>Cc Keir Fraser <[email protected]>Cc Konstantin Khlebnikov <[email protected]>Cc Li Zhe <[email protected]>Cc Matthew Wilcox (Oracle) <[email protected]>Cc Peter Xu <[email protected]>Cc Rik van Riel <[email protected]>Cc Shivank Garg <[email protected]>Cc Vlastimil Babka <[email protected]>Cc Wei Xu <[email protected]>Cc Will Deacon <[email protected]>Cc yangge <[email protected]>Cc Yuanchu Xie <[email protected]>Cc Yu Zhao <[email protected]>Cc <[email protected]>Signed-off-by Andrew Morton <[email protected]>[ adapted to drain_allow instead of drained ]Signed-off-by Sasha Levin <[email protected]>Quoted 1 line
---
Quoted 2 lines
Does not apply as it conflicts with the other mm changes you sent right before this one :(
Thanks for grabbing all these, I'm sorry they are troublesome.
Though I'm usually able to work out what to do from the FAILED mails, in this case I'd just be guessing without the full contexts. So I'll wait until I see what goes into the various branches of linux-stable-rc.git before checking and adjusting where necessary.
(As usual, I'll tend towards minimal change, where Sasha tends towards maximal backporting of encroaching mods: we may disagree.)
Quoted 7 lines
Quoted 4 lines
The main commits contributing to the pinning failures that Will Deacon reported were commits going into 5.18 and 6.11. So although I stand by my Fixes tag, I'm likely to conclude that 5.15 and 5.10 and 5.4 are better left stable without any of it.
That suits me. 6.1, 6.6 and 6.12 are the main ones that I'm concerned with from the Android side.
I'll hold off on backports then :)
Signature · 2 lines
Thanks, Sasha
Re: [PATCH 6.12.y] mm: folio_may_be_lru_cached() unless folio_test_large()
Quoted 78 lines · Sasha Levin
Quoted 77 lines · Will Deacon
Quoted 75 lines · Hugh Dickins
Quoted 57 lines · Greg KH
Quoted 54 lines · Sasha Levin
From: Hugh Dickins <[email protected]>
[ Upstream commit
2da6de30e60dd9bb14600eff1cc99df2fa2ddae3]
mm/swap.candmm/mlock.cagree to drain any per-CPU batch as soon as a large folio is added: socollect_longterm_unpinnable_folios()just wastes
effort when calling lru_add_drain[_all]() on a large folio.But although there is good reason not to batch up PMD-sized folios, we might well benefit from batching a small number of low-order mTHPs (though
unclear how that "small number" limitation will be implemented).So ask if
folio_may_be_lru_cached()rather than !folio_test_large(), to insulate those particular checks from future change. Name preferred to "folio_is_batchable" because large folios can well be put on a batch:
it's
just the per-CPU LRU caches, drained much later, which need care.Marked for stable, to counter the increase in lru_add_drain_all()s from "mm/gup: check
ref_countinstead of lru before migration".Link:
https://lkml.kernel.org/r/[email protected]Fixes 9a4e9f3b2d73 ("mm: update get_user_pages_longterm to migratepages allocated from CMA region")
Signed-off-by Hugh Dickins <[email protected]>Suggested-by David Hildenbrand <[email protected]>Cc "Aneesh Kumar K.V" <[email protected]>Cc Axel Rasmussen <[email protected]>Cc Chris Li <[email protected]>Cc Christoph Hellwig <[email protected]>Cc Jason Gunthorpe <[email protected]>Cc Johannes Weiner <[email protected]>Cc John Hubbard <[email protected]>Cc Keir Fraser <[email protected]>Cc Konstantin Khlebnikov <[email protected]>Cc Li Zhe <[email protected]>Cc Matthew Wilcox (Oracle) <[email protected]>Cc Peter Xu <[email protected]>Cc Rik van Riel <[email protected]>Cc Shivank Garg <[email protected]>Cc Vlastimil Babka <[email protected]>Cc Wei Xu <[email protected]>Cc Will Deacon <[email protected]>Cc yangge <[email protected]>Cc Yuanchu Xie <[email protected]>Cc Yu Zhao <[email protected]>Cc <[email protected]>Signed-off-by Andrew Morton <[email protected]>[ adapted to drain_allow instead of drained ]Signed-off-by Sasha Levin <[email protected]>Quoted 1 line
---
Quoted 2 lines
Does not apply as it conflicts with the other mm changes you sent right before this one :(
Thanks for grabbing all these, I'm sorry they are troublesome.
Though I'm usually able to work out what to do from the FAILED mails, in this case I'd just be guessing without the full contexts. So I'll wait until I see what goes into the various branches of linux-stable-rc.git before checking and adjusting where necessary.
(As usual, I'll tend towards minimal change, where Sasha tends towards maximal backporting of encroaching mods: we may disagree.)
The main commits contributing to the pinning failures that Will Deacon reported were commits going into 5.18 and 6.11. So although I stand by my Fixes tag, I'm likely to conclude that 5.15 and 5.10 and 5.4 are better left stable without any of it.
Quoted 4 lines
Quoted 2 lines
That suits me. 6.1, 6.6 and 6.12 are the main ones that I'm concerned with from the Android side.
I'll hold off on backports then :)
Sure :)
I'm fading: let me explain and send what I have so far.
6.16.9-rc1 is fine, no further change needed from me, thanks.
6.12.49-rc1 is okay with what's in it already, but needs the missing three patches on top, attached.
0001*patch and 0003*patch are actually just clean cherry-picks, I expect the 0001*patch FAILED originally because of needing a Stable-dep, which later did get into the rc1 tree. If you prefer, feel free to ignore my attached 0001*patch and 0003*patch (with my additional Signoffs), cherry-pick for yourself, and just apply my 0002*patch between them.
6.6.108-rc1 (not yet posted, but there in linux-stable-rc.git):
sensibly does not yet contain any of the lrudrain series, I'm assembling them, but just hit a snag - I've noticed that the 6.6-stable mm/gup.c collect_longterm_unpinnable_pages(), which I'm patching, contains a mod which was later reverted in Linus's tree, the revert was marked for stable but I expect it ended up as FAILED, so I need to spend more time looking into that (6.14 1aaf8c122918 reverted by 6.16 517f496e1e61): not tonight.
After I've settled 6.6, I'll move on to 6.1, but no further.
Hugh
From 7affc63035963917e25a798a8c22065cd06dcefb Mon Sep 17 00:00:00 2001
From: Hugh Dickins <[email protected]>
Date: Mon, 8 Sep 2025 15:16:53 -0700
Subject: [PATCH 1/3] mm/gup: local lru_add_drain() to avoid
lru_add_drain_all()
[ Upstream commit a09a8a1fbb374e0053b97306da9dbc05bd384685 ]
In many cases, if collect_longterm_unpinnable_folios() does need to drain the LRU cache to release a reference, the cache in question is on this same CPU, and much more efficiently drained by a preliminary local lru_add_drain(), than the later cross-CPU lru_add_drain_all().
Marked for stable, to counter the increase in lru_add_drain_all()s from "mm/gup: check ref_count instead of lru before migration". Note for clean
backports: can take 6.16 commit a03db236aebf ("gup: optimize longterm pin_user_pages() for large folio") first.
--- mm/gup.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-)
mm/gup.c +11 -4
@@ -2356,8 +2356,8 @@ static unsigned long collect_longterm_unpinnable_folios( struct pages_or_folios *pofs) {unsigned long collected =0 ; -bool drain_allow = true;struct folio *folio; +int drained =0 ;long i =0 ; for (folio = pofs_get_folio(pofs, i); folio;
@@ -2376,10 +2376,17 @@ static unsigned long collect_longterm_unpinnable_folios(continue ; } -if (drain_allow &&folio_ref_count (folio) != -folio_expected_ref_count (folio) +1 ) { +if (drained ==0 && +folio_ref_count (folio) != +folio_expected_ref_count (folio) +1 ) { +lru_add_drain (); + drained =1 ; + } +if (drained ==1 && +folio_ref_count (folio) != +folio_expected_ref_count (folio) +1 ) {lru_add_drain_all (); - drain_allow = false; + drained =2 ; }if (!folio_isolate_lru (folio))
Signature · 1 line
2.51.0.534.gc79095c0ca-goog
From 39531c7ef37d9279da2cbdc6b9d7ba73824a8e6b Mon Sep 17 00:00:00 2001
From: Hugh Dickins <[email protected]>
Date: Mon, 8 Sep 2025 15:19:17 -0700
Subject: [PATCH 2/3] mm: revert "mm/gup: clear the LRU flag of a page before
adding to LRU batch"
[ Upstream commit afb99e9f500485160f34b8cad6d3763ada3e80e8 ]
This reverts commit 33dfe9204f29: now that collect_longterm_unpinnable_folios() is checking ref_count instead of lru, and mlock/munlock do not participate in the revised LRU flag clearing, those changes are misleading, and enlarge the window during which mlock/munlock may miss an mlock_count update.
It is possible (I'd hesitate to claim probable) that the greater likelihood of missed mlock_count updates would explain the "Realtime threads delayed due to kcompactd0" observed on 6.12 in the Link below. If that is the case, this reversion will help; but a complete solution needs also a further patch, beyond the scope of this series.
Included some 80-column cleanup around folio_batch_add_and_move().
The role of folio_test_clear_lru() (before taking per-memcg lru_lock) is questionable since 6.13 removed mem_cgroup_move_account() etc; but perhaps there are still some races which need it - not examined here.
--- mm/swap.c | 51 +++++++++++++++++++++++++++------------------------ 1 file changed, 27 insertions(+), 24 deletions(-)
mm/swap.c +27 -24
125 lines not on this page · raw message
Signature · 1 line
2.51.0.534.gc79095c0ca-goog
From 7450544bc820b0c884a10e2348b8514166dab5cb Mon Sep 17 00:00:00 2001
From: Hugh Dickins <[email protected]>
Date: Mon, 8 Sep 2025 15:23:15 -0700
Subject: [PATCH 3/3] mm: folio_may_be_lru_cached() unless folio_test_large()
[ Upstream commit 2da6de30e60dd9bb14600eff1cc99df2fa2ddae3 ]
mm/swap.c and mm/mlock.c agree to drain any per-CPU batch as soon as a large folio is added: so collect_longterm_unpinnable_folios() just wastes effort when calling lru_add_drain[_all]() on a large folio.
But although there is good reason not to batch up PMD-sized folios, we might well benefit from batching a small number of low-order mTHPs (though unclear how that "small number" limitation will be implemented).
So ask if folio_may_be_lru_cached() rather than !folio_test_large(), to insulate those particular checks from future change. Name preferred to "folio_is_batchable" because large folios can well be put on a batch: it's just the per-CPU LRU caches, drained much later, which need care.
Marked for stable, to counter the increase in lru_add_drain_all()s from "mm/gup: check ref_count instead of lru before migration".
--- include/linux/swap.h | 10 ++++++++++ mm/gup.c | 4 ++-- mm/mlock.c | 6 +++--- mm/swap.c | 2 +- 4 files changed, 16 insertions(+), 6 deletions(-)
include/linux/swap.h +10 -0
@@ -382,6 +382,16 @@ void folio_add_lru_vma(struct folio *, struct vm_area_struct *);void mark_page_accessed (struct page *);void folio_mark_accessed (struct folio *); +static inline bool folio_may_be_lru_cached (struct folio *folio) +{ +/* +* Holding PMD-sized folios in per-CPU LRU cache unbalances accounting. +* Holding small numbers of low-order mTHP folios in per-CPU LRU cache +* will be sensible, but nobody has implemented and tested that yet. +*/ +return !folio_test_large (folio); +} +extern atomic_t lru_disable_count;static inline bool lru_cache_disabled (void )
mm/gup.c +2 -2
@@ -2376,13 +2376,13 @@ static unsigned long collect_longterm_unpinnable_folios(continue ; } -if (drained ==0 && +if (drained ==0 &&folio_may_be_lru_cached (folio) &&folio_ref_count (folio) !=folio_expected_ref_count (folio) +1 ) {lru_add_drain (); drained =1 ; } -if (drained ==1 && +if (drained ==1 &&folio_may_be_lru_cached (folio) &&folio_ref_count (folio) !=folio_expected_ref_count (folio) +1 ) {lru_add_drain_all ();
mm/mlock.c +3 -3
@@ -255,7 +255,7 @@ void mlock_folio(struct folio *folio)folio_get (folio);if (!folio_batch_add (fbatch,mlock_lru (folio)) || -folio_test_large (folio) ||lru_cache_disabled ()) + !folio_may_be_lru_cached (folio) ||lru_cache_disabled ())mlock_folio_batch (fbatch);local_unlock (&mlock_fbatch.lock); }
@@ -278,7 +278,7 @@ void mlock_new_folio(struct folio *folio)folio_get (folio);if (!folio_batch_add (fbatch,mlock_new (folio)) || -folio_test_large (folio) ||lru_cache_disabled ()) + !folio_may_be_lru_cached (folio) ||lru_cache_disabled ())mlock_folio_batch (fbatch);local_unlock (&mlock_fbatch.lock); }
@@ -299,7 +299,7 @@ void munlock_folio(struct folio *folio)*/ folio_get (folio);if (!folio_batch_add (fbatch, folio) || -folio_test_large (folio) ||lru_cache_disabled ()) + !folio_may_be_lru_cached (folio) ||lru_cache_disabled ())mlock_folio_batch (fbatch);local_unlock (&mlock_fbatch.lock); }
mm/swap.c +1 -1
@@ -223,7 +223,7 @@ static void __folio_batch_add_and_move(struct folio_batch __percpu *fbatch,local_lock (&cpu_fbatches.lock);if (!folio_batch_add (this_cpu_ptr (fbatch), folio) || -folio_test_large (folio) ||lru_cache_disabled ()) + !folio_may_be_lru_cached (folio) ||lru_cache_disabled ())folio_batch_move_lru (this_cpu_ptr (fbatch), move_fn);if (disable_irq)
Signature · 1 line
2.51.0.534.gc79095c0ca-goog