* [PATCH mm-new] mm: vmscan: put rotation-missed folios at the LRU tail
@ 2026-09-20 4:30 Ridong Chen
2026-09-20 6:10 ` Ridong Chen
2026-09-20 9:21 ` Barry Song
0 siblings, 2 replies; 4+ messages in thread
From: Ridong Chen @ 2026-09-20 4:30 UTC (permalink / raw)
To: Andrew Morton, Johannes Weiner
Cc: Kairui Song, Qi Zheng, Shakeel Butt, Barry Song, Axel Rasmussen,
Yuanchu Xie, Wei Xu, Baoquan He, Baolin Wang, David Hildenbrand,
Michal Hocko, Lorenzo Stoakes,
open list:MEMORY MANAGEMENT - MGLRU (MULTI-GEN LRU),
linux-kernel, Ridong Chen, Ridong Chen
From: Ridong Chen <chenridong@xiaomi.com>
The page reclaim isolates a batch of folios from the tail of an LRU list
and works on them one by one. For a suitable swap-backed folio on an
async swap device, it queues the folio for writeback and, after finishing
the batch, puts the folio back to the head of the original LRU list.
Meanwhile the page writeback flushes the queued folios in its own,
independent batches. For each folio it writes back it calls
folio_rotate_reclaimable(), which tries to rotate the folio to the LRU
tail. But folio_rotate_reclaimable() only takes effect once the folio has
been put back by reclaim. If the async swap device is fast enough, the
writeback can complete a folio while reclaim is still working on the rest
of the batch that contains it. In that case the folio stays near the head
and reclaim will not revisit it before wrapping around, causing a cold/hot
inversion: a clean, written-back folio that should be a prime reclaim
candidate is kept ahead of hotter folios.
commit 359a5e1416ca ("mm: multi-gen LRU: retry folios written back while
isolated") addressed this for MGLRU only. The traditional active/inactive
LRU has the same problem, reported at [1]. A reproducer is available at
[2].
Rather than re-reclaiming those folios (which would drop the swap cache
that may still be useful for a future hit [4]), restore the rotation that
was missed: when move_folios_to_lru() puts a folio back, add it to the LRU
tail if it looks like it missed folio_rotate_reclaimable() (inactive, not
mapped, not dirty and not under writeback). A new do_rotate parameter
gates this so it only applies on the reclaim put-back path
(shrink_inactive_list()), not on shrink_active_list() where the list order
is already deliberate. This approach was suggested by Barry Song [3].
Only the traditional LRU is handled here. MGLRU already retries such
folios via its own clean-list retry pass in evict_folios(), so it is left
unchanged. The same do_rotate scheme could later replace that retry pass
to unify both LRUs, which is left for a follow-up.
[1] https://lore.kernel.org/linux-kernel/20241010081802.290893-1-chenridong@huaweicloud.com/
[2] https://lore.kernel.org/lkml/46037a37-4cf6-448e-a94b-30a4d16e8814@linux.dev/
[3] https://lore.kernel.org/lkml/CAGsJ_4zwP3_+EYY5Ug9EJ+yD1UdxsBSGr25u8s1K3u_i7LH3Zg@mail.gmail.com/
[4] https://lore.kernel.org/linux-mm/20260911121341.178028-1-alex@ghiti.fr/
Suggested-by: Barry Song <baohua@kernel.org>
Signed-off-by: Ridong Chen <chenridong@xiaomi.com>
---
mm/vmscan.c | 21 +++++++++++++++------
1 file changed, 15 insertions(+), 6 deletions(-)
diff --git a/mm/vmscan.c b/mm/vmscan.c
index e200ce3eb056..026b844c681f 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -1971,7 +1971,7 @@ static bool too_many_isolated(struct pglist_data *pgdat, int file,
*
* Note: The caller must not hold any lruvec lock.
*/
-static unsigned int move_folios_to_lru(struct list_head *list)
+static unsigned int move_folios_to_lru(struct list_head *list, bool do_rotate)
{
int nr_pages, nr_moved = 0;
struct lruvec *lruvec = NULL;
@@ -2018,7 +2018,16 @@ static unsigned int move_folios_to_lru(struct list_head *list)
continue;
}
- lruvec_add_folio(lruvec, folio);
+ /*
+ * Put folios that may have missed folio_rotate_reclaimable()
+ * at the tail to avoid cold/hot inversion.
+ */
+ if (do_rotate && !folio_test_active(folio) && !folio_mapped(folio) &&
+ !folio_test_dirty(folio) && !folio_test_writeback(folio))
+ lruvec_add_folio_tail(lruvec, folio);
+ else
+ lruvec_add_folio(lruvec, folio);
+
nr_pages = folio_nr_pages(folio);
nr_moved += nr_pages;
if (folio_test_active(folio))
@@ -2135,7 +2144,7 @@ static unsigned long shrink_inactive_list(unsigned long nr_to_scan,
nr_reclaimed = shrink_folio_list(&folio_list, pgdat, sc, &stat, false,
lruvec_memcg(lruvec));
- move_folios_to_lru(&folio_list);
+ move_folios_to_lru(&folio_list, true);
mod_lruvec_state(lruvec, PGDEMOTE_KSWAPD + reclaimer_offset(sc),
stat.nr_demoted);
@@ -2246,8 +2255,8 @@ static void shrink_active_list(unsigned long nr_to_scan,
/*
* Move folios back to the lru list.
*/
- nr_activate = move_folios_to_lru(&l_active);
- nr_deactivate = move_folios_to_lru(&l_inactive);
+ nr_activate = move_folios_to_lru(&l_active, false);
+ nr_deactivate = move_folios_to_lru(&l_inactive, false);
count_vm_events(PGDEACTIVATE, nr_deactivate);
count_memcg_events(lruvec_memcg(lruvec), PGDEACTIVATE, nr_deactivate);
@@ -5115,7 +5124,7 @@ static int evict_folios(unsigned long nr_to_scan, struct lruvec *lruvec,
folio_set_active(folio);
}
- move_folios_to_lru(&list);
+ move_folios_to_lru(&list, false);
walk = current->reclaim_state->mm_walk;
if (walk && walk->batched) {
--
2.34.1
^ permalink raw reply [flat|nested] 4+ messages in thread* Re: [PATCH mm-new] mm: vmscan: put rotation-missed folios at the LRU tail
2026-09-20 4:30 [PATCH mm-new] mm: vmscan: put rotation-missed folios at the LRU tail Ridong Chen
@ 2026-09-20 6:10 ` Ridong Chen
2026-09-20 9:21 ` Barry Song
1 sibling, 0 replies; 4+ messages in thread
From: Ridong Chen @ 2026-09-20 6:10 UTC (permalink / raw)
To: Andrew Morton, Johannes Weiner
Cc: Kairui Song, Qi Zheng, Shakeel Butt, Barry Song, Axel Rasmussen,
Yuanchu Xie, Wei Xu, Baoquan He, Baolin Wang, David Hildenbrand,
Michal Hocko, Lorenzo Stoakes,
open list:MEMORY MANAGEMENT - MGLRU (MULTI-GEN LRU),
linux-kernel, Ridong Chen
On 9/20/2026 12:30 PM, Ridong Chen wrote:
> From: Ridong Chen <chenridong@xiaomi.com>
>
> The page reclaim isolates a batch of folios from the tail of an LRU list
> and works on them one by one. For a suitable swap-backed folio on an
> async swap device, it queues the folio for writeback and, after finishing
> the batch, puts the folio back to the head of the original LRU list.
>
> Meanwhile the page writeback flushes the queued folios in its own,
> independent batches. For each folio it writes back it calls
> folio_rotate_reclaimable(), which tries to rotate the folio to the LRU
> tail. But folio_rotate_reclaimable() only takes effect once the folio has
> been put back by reclaim. If the async swap device is fast enough, the
> writeback can complete a folio while reclaim is still working on the rest
> of the batch that contains it. In that case the folio stays near the head
> and reclaim will not revisit it before wrapping around, causing a cold/hot
> inversion: a clean, written-back folio that should be a prime reclaim
> candidate is kept ahead of hotter folios.
>
> commit 359a5e1416ca ("mm: multi-gen LRU: retry folios written back while
> isolated") addressed this for MGLRU only. The traditional active/inactive
> LRU has the same problem, reported at [1]. A reproducer is available at
> [2].
>
> Rather than re-reclaiming those folios (which would drop the swap cache
> that may still be useful for a future hit [4]), restore the rotation that
> was missed: when move_folios_to_lru() puts a folio back, add it to the LRU
> tail if it looks like it missed folio_rotate_reclaimable() (inactive, not
> mapped, not dirty and not under writeback). A new do_rotate parameter
> gates this so it only applies on the reclaim put-back path
> (shrink_inactive_list()), not on shrink_active_list() where the list order
> is already deliberate. This approach was suggested by Barry Song [3].
>
Add test result:
```
Without patch:
cat memory.usage_in_bytes
1073700864
cat memory.memsw.usage_in_bytes
1413124096
free -h
total used free
Mem: 1.6Gi 1.2Gi 299Mi
Swap: 1.0Gi 678Mi 346Mi
With patch:
cat memory.usage_in_bytes
1071140864 bytes
cat memory.memsw.usage_in_bytes
1413423104 bytes
free -h
total used free
Mem: 1.6Gi 1.2Gi 322Mi
Swap: 1.0Gi 328Mi 695Mi
```
After applying the patch, the difference between
memory.memsw.usage_in_bytes and memory.usage_in_bytes is close to the
swap "used" value reported by 'free -h;.
This yields the same result as the 'retry' approach in v9 [1].
[1] https://lore.kernel.org/lkml/20260916123846.1242548-1-ridong.chen@linux.dev/
> Only the traditional LRU is handled here. MGLRU already retries such
> folios via its own clean-list retry pass in evict_folios(), so it is left
> unchanged. The same do_rotate scheme could later replace that retry pass
> to unify both LRUs, which is left for a follow-up.
>
> [1] https://lore.kernel.org/linux-kernel/20241010081802.290893-1-chenridong@huaweicloud.com/
> [2] https://lore.kernel.org/lkml/46037a37-4cf6-448e-a94b-30a4d16e8814@linux.dev/
> [3] https://lore.kernel.org/lkml/CAGsJ_4zwP3_+EYY5Ug9EJ+yD1UdxsBSGr25u8s1K3u_i7LH3Zg@mail.gmail.com/
> [4] https://lore.kernel.org/linux-mm/20260911121341.178028-1-alex@ghiti.fr/
>
> Suggested-by: Barry Song <baohua@kernel.org>
> Signed-off-by: Ridong Chen <chenridong@xiaomi.com>
> ---
> mm/vmscan.c | 21 +++++++++++++++------
> 1 file changed, 15 insertions(+), 6 deletions(-)
>
> diff --git a/mm/vmscan.c b/mm/vmscan.c
> index e200ce3eb056..026b844c681f 100644
> --- a/mm/vmscan.c
> +++ b/mm/vmscan.c
> @@ -1971,7 +1971,7 @@ static bool too_many_isolated(struct pglist_data *pgdat, int file,
> *
> * Note: The caller must not hold any lruvec lock.
> */
> -static unsigned int move_folios_to_lru(struct list_head *list)
> +static unsigned int move_folios_to_lru(struct list_head *list, bool do_rotate)
> {
> int nr_pages, nr_moved = 0;
> struct lruvec *lruvec = NULL;
> @@ -2018,7 +2018,16 @@ static unsigned int move_folios_to_lru(struct list_head *list)
> continue;
> }
>
> - lruvec_add_folio(lruvec, folio);
> + /*
> + * Put folios that may have missed folio_rotate_reclaimable()
> + * at the tail to avoid cold/hot inversion.
> + */
> + if (do_rotate && !folio_test_active(folio) && !folio_mapped(folio) &&
> + !folio_test_dirty(folio) && !folio_test_writeback(folio))
> + lruvec_add_folio_tail(lruvec, folio);
> + else
> + lruvec_add_folio(lruvec, folio);
> +
> nr_pages = folio_nr_pages(folio);
> nr_moved += nr_pages;
> if (folio_test_active(folio))
> @@ -2135,7 +2144,7 @@ static unsigned long shrink_inactive_list(unsigned long nr_to_scan,
> nr_reclaimed = shrink_folio_list(&folio_list, pgdat, sc, &stat, false,
> lruvec_memcg(lruvec));
>
> - move_folios_to_lru(&folio_list);
> + move_folios_to_lru(&folio_list, true);
>
> mod_lruvec_state(lruvec, PGDEMOTE_KSWAPD + reclaimer_offset(sc),
> stat.nr_demoted);
> @@ -2246,8 +2255,8 @@ static void shrink_active_list(unsigned long nr_to_scan,
> /*
> * Move folios back to the lru list.
> */
> - nr_activate = move_folios_to_lru(&l_active);
> - nr_deactivate = move_folios_to_lru(&l_inactive);
> + nr_activate = move_folios_to_lru(&l_active, false);
> + nr_deactivate = move_folios_to_lru(&l_inactive, false);
>
> count_vm_events(PGDEACTIVATE, nr_deactivate);
> count_memcg_events(lruvec_memcg(lruvec), PGDEACTIVATE, nr_deactivate);
> @@ -5115,7 +5124,7 @@ static int evict_folios(unsigned long nr_to_scan, struct lruvec *lruvec,
> folio_set_active(folio);
> }
>
> - move_folios_to_lru(&list);
> + move_folios_to_lru(&list, false);
>
> walk = current->reclaim_state->mm_walk;
> if (walk && walk->batched) {
--
Best regards
Ridong
^ permalink raw reply [flat|nested] 4+ messages in thread* Re: [PATCH mm-new] mm: vmscan: put rotation-missed folios at the LRU tail
2026-09-20 4:30 [PATCH mm-new] mm: vmscan: put rotation-missed folios at the LRU tail Ridong Chen
2026-09-20 6:10 ` Ridong Chen
@ 2026-09-20 9:21 ` Barry Song
2026-09-20 11:12 ` Ridong Chen
1 sibling, 1 reply; 4+ messages in thread
From: Barry Song @ 2026-09-20 9:21 UTC (permalink / raw)
To: Ridong Chen
Cc: Andrew Morton, Johannes Weiner, Kairui Song, Qi Zheng,
Shakeel Butt, Axel Rasmussen, Yuanchu Xie, Wei Xu, Baoquan He,
Baolin Wang, David Hildenbrand, Michal Hocko, Lorenzo Stoakes,
open list:MEMORY MANAGEMENT - MGLRU (MULTI-GEN LRU),
linux-kernel, Ridong Chen
On Sun, Sep 20, 2026 at 12:30 PM Ridong Chen <ridong.chen@linux.dev> wrote:
>
> From: Ridong Chen <chenridong@xiaomi.com>
>
> The page reclaim isolates a batch of folios from the tail of an LRU list
> and works on them one by one. For a suitable swap-backed folio on an
> async swap device, it queues the folio for writeback and, after finishing
> the batch, puts the folio back to the head of the original LRU list.
>
> Meanwhile the page writeback flushes the queued folios in its own,
> independent batches. For each folio it writes back it calls
> folio_rotate_reclaimable(), which tries to rotate the folio to the LRU
> tail. But folio_rotate_reclaimable() only takes effect once the folio has
> been put back by reclaim. If the async swap device is fast enough, the
> writeback can complete a folio while reclaim is still working on the rest
> of the batch that contains it. In that case the folio stays near the head
> and reclaim will not revisit it before wrapping around, causing a cold/hot
> inversion: a clean, written-back folio that should be a prime reclaim
> candidate is kept ahead of hotter folios.
>
> commit 359a5e1416ca ("mm: multi-gen LRU: retry folios written back while
> isolated") addressed this for MGLRU only. The traditional active/inactive
> LRU has the same problem, reported at [1]. A reproducer is available at
> [2].
>
> Rather than re-reclaiming those folios (which would drop the swap cache
> that may still be useful for a future hit [4]), restore the rotation that
> was missed: when move_folios_to_lru() puts a folio back, add it to the LRU
> tail if it looks like it missed folio_rotate_reclaimable() (inactive, not
> mapped, not dirty and not under writeback). A new do_rotate parameter
> gates this so it only applies on the reclaim put-back path
> (shrink_inactive_list()), not on shrink_active_list() where the list order
> is already deliberate. This approach was suggested by Barry Song [3].
>
> Only the traditional LRU is handled here. MGLRU already retries such
> folios via its own clean-list retry pass in evict_folios(), so it is left
> unchanged. The same do_rotate scheme could later replace that retry pass
> to unify both LRUs, which is left for a follow-up.
>
> [1] https://lore.kernel.org/linux-kernel/20241010081802.290893-1-chenridong@huaweicloud.com/
> [2] https://lore.kernel.org/lkml/46037a37-4cf6-448e-a94b-30a4d16e8814@linux.dev/
> [3] https://lore.kernel.org/lkml/CAGsJ_4zwP3_+EYY5Ug9EJ+yD1UdxsBSGr25u8s1K3u_i7LH3Zg@mail.gmail.com/
> [4] https://lore.kernel.org/linux-mm/20260911121341.178028-1-alex@ghiti.fr/
>
> Suggested-by: Barry Song <baohua@kernel.org>
> Signed-off-by: Ridong Chen <chenridong@xiaomi.com>
> ---
> mm/vmscan.c | 21 +++++++++++++++------
> 1 file changed, 15 insertions(+), 6 deletions(-)
>
> diff --git a/mm/vmscan.c b/mm/vmscan.c
> index e200ce3eb056..026b844c681f 100644
> --- a/mm/vmscan.c
> +++ b/mm/vmscan.c
> @@ -1971,7 +1971,7 @@ static bool too_many_isolated(struct pglist_data *pgdat, int file,
> *
> * Note: The caller must not hold any lruvec lock.
> */
> -static unsigned int move_folios_to_lru(struct list_head *list)
> +static unsigned int move_folios_to_lru(struct list_head *list, bool do_rotate)
> {
> int nr_pages, nr_moved = 0;
> struct lruvec *lruvec = NULL;
> @@ -2018,7 +2018,16 @@ static unsigned int move_folios_to_lru(struct list_head *list)
> continue;
> }
>
> - lruvec_add_folio(lruvec, folio);
> + /*
> + * Put folios that may have missed folio_rotate_reclaimable()
> + * at the tail to avoid cold/hot inversion.
> + */
> + if (do_rotate && !folio_test_active(folio) && !folio_mapped(folio) &&
> + !folio_test_dirty(folio) && !folio_test_writeback(folio))
> + lruvec_add_folio_tail(lruvec, folio);
sashiko says:
"Could this heuristic indiscriminately place un-reclaimable clean folios at
the LRU tail, ensuring they are immediately re-scanned in an infinite loop?
If shrink_inactive_list() isolates a clean, unmapped file folio with an
elevated refcount (such as from a concurrent GUP or speculative lookup),
it will fail __remove_mapping() and be placed on ret_folios.
Because this pinned folio matches the !active, !mapped, !dirty, and
!writeback checks, it is placed at the tail of the inactive LRU. The very
next isolate_lru_folios() pull from the tail will immediately isolate this
exact same folio again, creating an infinite loop that prevents any other
folios from being reclaimed and causes kswapd to spin at 100% CPU."
This seems to be a valid concern. For a clean and unmapped folio, we
may still fail in `__remove_mapping()` if it is pinned somewhere. So
perhaps we can add a refcount check when fixing the rotation.
Best Regards
Barry
^ permalink raw reply [flat|nested] 4+ messages in thread* Re: [PATCH mm-new] mm: vmscan: put rotation-missed folios at the LRU tail
2026-09-20 9:21 ` Barry Song
@ 2026-09-20 11:12 ` Ridong Chen
0 siblings, 0 replies; 4+ messages in thread
From: Ridong Chen @ 2026-09-20 11:12 UTC (permalink / raw)
To: Barry Song
Cc: Andrew Morton, Johannes Weiner, Kairui Song, Qi Zheng,
Shakeel Butt, Axel Rasmussen, Yuanchu Xie, Wei Xu, Baoquan He,
Baolin Wang, David Hildenbrand, Michal Hocko, Lorenzo Stoakes,
open list:MEMORY MANAGEMENT - MGLRU (MULTI-GEN LRU),
linux-kernel, Ridong Chen
On 9/20/2026 5:21 PM, Barry Song wrote:
> On Sun, Sep 20, 2026 at 12:30 PM Ridong Chen <ridong.chen@linux.dev> wrote:
>>
>> From: Ridong Chen <chenridong@xiaomi.com>
>>
>> The page reclaim isolates a batch of folios from the tail of an LRU list
>> and works on them one by one. For a suitable swap-backed folio on an
>> async swap device, it queues the folio for writeback and, after finishing
>> the batch, puts the folio back to the head of the original LRU list.
>>
>> Meanwhile the page writeback flushes the queued folios in its own,
>> independent batches. For each folio it writes back it calls
>> folio_rotate_reclaimable(), which tries to rotate the folio to the LRU
>> tail. But folio_rotate_reclaimable() only takes effect once the folio has
>> been put back by reclaim. If the async swap device is fast enough, the
>> writeback can complete a folio while reclaim is still working on the rest
>> of the batch that contains it. In that case the folio stays near the head
>> and reclaim will not revisit it before wrapping around, causing a cold/hot
>> inversion: a clean, written-back folio that should be a prime reclaim
>> candidate is kept ahead of hotter folios.
>>
>> commit 359a5e1416ca ("mm: multi-gen LRU: retry folios written back while
>> isolated") addressed this for MGLRU only. The traditional active/inactive
>> LRU has the same problem, reported at [1]. A reproducer is available at
>> [2].
>>
>> Rather than re-reclaiming those folios (which would drop the swap cache
>> that may still be useful for a future hit [4]), restore the rotation that
>> was missed: when move_folios_to_lru() puts a folio back, add it to the LRU
>> tail if it looks like it missed folio_rotate_reclaimable() (inactive, not
>> mapped, not dirty and not under writeback). A new do_rotate parameter
>> gates this so it only applies on the reclaim put-back path
>> (shrink_inactive_list()), not on shrink_active_list() where the list order
>> is already deliberate. This approach was suggested by Barry Song [3].
>>
>> Only the traditional LRU is handled here. MGLRU already retries such
>> folios via its own clean-list retry pass in evict_folios(), so it is left
>> unchanged. The same do_rotate scheme could later replace that retry pass
>> to unify both LRUs, which is left for a follow-up.
>>
>> [1] https://lore.kernel.org/linux-kernel/20241010081802.290893-1-chenridong@huaweicloud.com/
>> [2] https://lore.kernel.org/lkml/46037a37-4cf6-448e-a94b-30a4d16e8814@linux.dev/
>> [3] https://lore.kernel.org/lkml/CAGsJ_4zwP3_+EYY5Ug9EJ+yD1UdxsBSGr25u8s1K3u_i7LH3Zg@mail.gmail.com/
>> [4] https://lore.kernel.org/linux-mm/20260911121341.178028-1-alex@ghiti.fr/
>>
>> Suggested-by: Barry Song <baohua@kernel.org>
>> Signed-off-by: Ridong Chen <chenridong@xiaomi.com>
>> ---
>> mm/vmscan.c | 21 +++++++++++++++------
>> 1 file changed, 15 insertions(+), 6 deletions(-)
>>
>> diff --git a/mm/vmscan.c b/mm/vmscan.c
>> index e200ce3eb056..026b844c681f 100644
>> --- a/mm/vmscan.c
>> +++ b/mm/vmscan.c
>> @@ -1971,7 +1971,7 @@ static bool too_many_isolated(struct pglist_data *pgdat, int file,
>> *
>> * Note: The caller must not hold any lruvec lock.
>> */
>> -static unsigned int move_folios_to_lru(struct list_head *list)
>> +static unsigned int move_folios_to_lru(struct list_head *list, bool do_rotate)
>> {
>> int nr_pages, nr_moved = 0;
>> struct lruvec *lruvec = NULL;
>> @@ -2018,7 +2018,16 @@ static unsigned int move_folios_to_lru(struct list_head *list)
>> continue;
>> }
>>
>> - lruvec_add_folio(lruvec, folio);
>> + /*
>> + * Put folios that may have missed folio_rotate_reclaimable()
>> + * at the tail to avoid cold/hot inversion.
>> + */
>> + if (do_rotate && !folio_test_active(folio) && !folio_mapped(folio) &&
>> + !folio_test_dirty(folio) && !folio_test_writeback(folio))
>> + lruvec_add_folio_tail(lruvec, folio);
>
> sashiko says:
>
> "Could this heuristic indiscriminately place un-reclaimable clean folios at
> the LRU tail, ensuring they are immediately re-scanned in an infinite loop?
> If shrink_inactive_list() isolates a clean, unmapped file folio with an
> elevated refcount (such as from a concurrent GUP or speculative lookup),
> it will fail __remove_mapping() and be placed on ret_folios.
> Because this pinned folio matches the !active, !mapped, !dirty, and
> !writeback checks, it is placed at the tail of the inactive LRU. The very
> next isolate_lru_folios() pull from the tail will immediately isolate this
> exact same folio again, creating an infinite loop that prevents any other
> folios from being reclaimed and causes kswapd to spin at 100% CPU."
>
> This seems to be a valid concern. For a clean and unmapped folio, we
> may still fail in `__remove_mapping()` if it is pinned somewhere. So
> perhaps we can add a refcount check when fixing the rotation.
>
Thanks, I will update.
--
Best regards
Ridong
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-09-20 11:12 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-20 4:30 [PATCH mm-new] mm: vmscan: put rotation-missed folios at the LRU tail Ridong Chen
2026-09-20 6:10 ` Ridong Chen
2026-09-20 9:21 ` Barry Song
2026-09-20 11:12 ` Ridong Chen
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®