Re: [RFC PATCH v3 4/4] mm/shmem: split large folios only on -E2BIG
From: Barry Song
Date: Tue Jul 21 2026 - 04:04:15 EST
On Fri, Jul 17, 2026 at 8:26 PM Xueyuan Chen <xueyuan.chen21@xxxxxxxxx> wrote:
>
> shmem_writeout() currently splits a large folio on every
> folio_alloc_swap() failure. With the refined return-value contract, only
> -E2BIG indicates that splitting might allow smaller folios to be swapped
> out.
>
> Enter the split fallback only for -E2BIG. For -ENOSPC and -ENOMEM,
> redirty and reactivate the folio as before.
>
> Suggested-by: Baolin Wang <baolin.wang@xxxxxxxxxxxxxxxxx>
> Signed-off-by: Xueyuan Chen <xueyuan.chen21@xxxxxxxxx>
> ---
> mm/shmem.c | 6 ++++--
> 1 file changed, 4 insertions(+), 2 deletions(-)
>
> diff --git a/mm/shmem.c b/mm/shmem.c
> index 3b5dc21b323c..d76812dd3cef 100644
> --- a/mm/shmem.c
> +++ b/mm/shmem.c
> @@ -1599,6 +1599,7 @@ int shmem_writeout(struct folio *folio, struct swap_iocb **plug,
> struct shmem_sb_info *sbinfo = SHMEM_SB(inode->i_sb);
> pgoff_t index;
> int nr_pages;
> + int ret;
> bool split = false;
>
> if ((info->flags & SHMEM_F_LOCKED) || sbinfo->noswap)
> @@ -1679,7 +1680,8 @@ int shmem_writeout(struct folio *folio, struct swap_iocb **plug,
> folio_mark_uptodate(folio);
> }
>
> - if (!folio_alloc_swap(folio)) {
> + ret = folio_alloc_swap(folio);
> + if (!ret) {
> bool first_swapped = shmem_recalc_inode(inode, 0, nr_pages);
> int error;
>
> @@ -1732,7 +1734,7 @@ int shmem_writeout(struct folio *folio, struct swap_iocb **plug,
> swap_cache_del_folio(folio);
> goto redirty;
> }
> - if (nr_pages > 1)
> + if (ret == -E2BIG)
I'd rather keep if (nr_pages > 1 && ret == -E2BIG), as it makes the large
folio case more explicit and easier to understand.
> goto try_split;
> redirty:
> folio_mark_dirty(folio);
Best Regards
Barry