Re: [PATCH v5 9/9] mm: switch deferred split shrinker to list_lru

From: Lance Yang

Date: Mon Jun 01 2026 - 09:24:16 EST



On Wed, May 27, 2026 at 04:45:16PM -0400, Johannes Weiner wrote:
[...]
>diff --git a/mm/swap_state.c b/mm/swap_state.c
>index 04f5ce992401..9c3a5cf99778 100644
>--- a/mm/swap_state.c
>+++ b/mm/swap_state.c
>@@ -465,6 +465,16 @@ static struct folio *__swap_cache_alloc(struct swap_cluster_info *ci,
> return ERR_PTR(-ENOMEM);
> }
>

Shouldn't this be limited to anon swapin?

e.g. vmf && vma_is_anonymous(vmf->vma)

>+ if (order > 1 && folio_memcg_alloc_deferred(folio)) {

__swap_cache_alloc() is also used by shmem direct swapin, so shmem can
get here too when handling a large swap entry:

shmem_get_folio_gfp()
shmem_swapin_folio()
shmem_swap_alloc_folio()
swapin_sync()
swap_cache_alloc_folio()
__swap_cache_alloc()
folio_memcg_alloc_deferred()

@Baolin please correct me if I got it wrong :)

folio_memcg_alloc_deferred() itself doesn't filter shmem out either; it
only allocates the memcg list_lru metadata for deferred_split_lru:

int folio_memcg_alloc_deferred(struct folio *folio)
{
if (mem_cgroup_disabled())
return 0;
return folio_memcg_list_lru_alloc(folio, &deferred_split_lru, GFP_KERNEL);
}

Since deferred_split_lru only queues anon large folios, doing this for
shmem swapin doesn't buy us anything :)

Maybe I'm missing something, just wanted to raise it.

>+ spin_lock(&ci->lock);
>+ __swap_cache_do_del_folio(ci, folio, entry, shadow);
>+ spin_unlock(&ci->lock);
>+ folio_unlock(folio);
>+ /* nr_pages refs from swap cache, 1 from allocation */
>+ folio_put_refs(folio, nr_pages + 1);
>+ return ERR_PTR(-ENOMEM);
>+ }
>+
> /* memsw uncharges swap when folio is added to swap cache */
> memcg1_swapin(folio);
> if (shadow)
>--
>2.54.0
>
>