Re: [RFC PATCH v3 3/4] mm/vmscan: avoid pointless large folio splits without swap

Barry Song <[email protected]>
Newsgroups org.kernel.vger.cgroups,org.kernel.vger.linux-kernel,org.kvack.linux-mm
Message-ID <CAGsJ_4yj3dYah2exFWLMwFhUysOz2U9ANyoESgdGKvRL0E_0zw@mail.gmail.com>
On Fri, Jul 17, 2026 at 8:25 PM Xueyuan Chen <[email protected]> wrote:
>
> From: "Barry Song (Xiaomi)" <[email protected]>
>
> When swap is disabled, exhausted, or unavailable due to memcg swap
> limits, splitting a large anonymous folio cannot make swapout progress.
> The fallback only destroys the large folio and inflates split statistics.
>
> Use -E2BIG from folio_alloc_swap() as the explicit signal that splitting
> the folio might allow swapout of smaller pieces. For other allocation
> failures, keep the existing activation path and avoid the split.
>
> This preserves the split fallback for fragmented or partially available
> swap, while avoiding it when there is no backing space for any part of the
> folio.
>
> Reported-by: Nanzhe Zhao <[email protected]>
> Signed-off-by: Barry Song (Xiaomi) <[email protected]>
> ---
>  mm/vmscan.c | 7 +++++--
>  1 file changed, 5 insertions(+), 2 deletions(-)
>
> diff --git a/mm/vmscan.c b/mm/vmscan.c
> index bd1b1aa12581..40340a88f78e 100644
> --- a/mm/vmscan.c
> +++ b/mm/vmscan.c
> @@ -1260,6 +1260,8 @@ static unsigned int shrink_folio_list(struct list_head *folio_list,
>                  */
>                 if (folio_test_anon(folio) && folio_test_swapbacked(folio) &&
>                                 !folio_test_swapcache(folio)) {
> +                       int ret;
> +
>                         if (!(sc->gfp_mask & __GFP_IO))
>                                 goto keep_locked;
>                         if (folio_maybe_dma_pinned(folio))
> @@ -1278,10 +1280,11 @@ static unsigned int shrink_folio_list(struct list_head *folio_list,
>                                     split_folio_to_list(folio, folio_list))
>                                         goto activate_locked;
>                         }
> -                       if (folio_alloc_swap(folio)) {
> +                       ret = folio_alloc_swap(folio);
> +                       if (ret) {
>                                 int __maybe_unused order = folio_order(folio);
>
> -                               if (!folio_test_large(folio))
> +                               if (!folio_test_large(folio) || ret != -E2BIG)

I'd rather split it into two checks:

if (!folio_test_large(folio))
         goto activate_locked_split;

if (ret != -E2BIG)
         goto activate_locked_split;

This makes it clear that ret != -E2BIG is only relevant for the large
folio case.


>                                         goto activate_locked_split;
>                                 /* Fallback to swap normal pages */
>                                 if (split_folio_to_list(folio, folio_list))
> --
> 2.47.3
>

Best Regards
Barry
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.