Re: [PATCH v3 1/4] mm: avoid unnecessary lru drain for wp_can_reuse_anon_folio()

From: Baoquan He

Date: Tue Jul 07 2026 - 08:59:37 EST


On 07/02/26 at 07:59am, Barry Song (Xiaomi) wrote:
> There is a case where `folio_ref_count(folio) == 3` and
> `!folio_test_swapcache(folio)`. In that case, both
> `folio_ref_count(folio) > 3` and
> `folio_ref_count(folio) > 1 + folio_test_swapcache(folio)` evaluate
> false, causing an unnecessary local LRU drain.
>
> During an Ubuntu boot, I observed over 5,000 redundant local LRU
> drains. For a kernel build with a minimal configuration, I observed
> more than 20,000 redundant drains.
>
> Fix this by checking against: `1 + in_swapcache + in_lrucache`
> instead of hardcoding `folio_ref_count(folio) > 3`.
>
> Suggested-by: David Hildenbrand (Arm) <david@xxxxxxxxxx>
> Reviewed-by: Kairui Song <kasong@xxxxxxxxxxx>
> Acked-by: Shakeel Butt <shakeel.butt@xxxxxxxxx>
> Reviewed-by: Baoquan He <baoquan.he@xxxxxxxxx>
> Signed-off-by: Barry Song (Xiaomi) <baohua@xxxxxxxxxx>
> ---
> mm/memory.c | 10 +++++++---
> 1 file changed, 7 insertions(+), 3 deletions(-)

Rechecked, LGTM,

Reviewed-by: Baoquan He <baoquan.he@xxxxxxxxx>

>
> diff --git a/mm/memory.c b/mm/memory.c
> index ff338c2abe92..87da78eb1abd 100644
> --- a/mm/memory.c
> +++ b/mm/memory.c
> @@ -4181,6 +4181,9 @@ static bool __wp_can_reuse_large_anon_folio(struct folio *folio,
> static bool wp_can_reuse_anon_folio(struct folio *folio,
> struct vm_area_struct *vma)
> {
> + const bool in_lru_cache = !folio_test_lru(folio);
> + const bool in_swapcache = folio_test_swapcache(folio);
> +
> if (IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE) && folio_test_large(folio))
> return __wp_can_reuse_large_anon_folio(folio, vma);
>
> @@ -4191,15 +4194,16 @@ static bool wp_can_reuse_anon_folio(struct folio *folio,
> *
> * KSM doesn't necessarily raise the folio refcount.
> */
> - if (folio_test_ksm(folio) || folio_ref_count(folio) > 3)
> + if (folio_test_ksm(folio) ||
> + folio_ref_count(folio) > 1 + in_lru_cache + in_swapcache)
> return false;
> - if (!folio_test_lru(folio))
> + if (in_lru_cache)
> /*
> * We cannot easily detect+handle references from
> * remote LRU caches or references to LRU folios.
> */
> lru_add_drain();
> - if (folio_ref_count(folio) > 1 + folio_test_swapcache(folio))
> + if (folio_ref_count(folio) > 1 + in_swapcache)
> return false;
> if (!folio_trylock(folio))
> return false;
> --
> 2.39.3 (Apple Git-146)
>