[RFC PATCH v3 4/4] mm/shmem: split large folios only on -E2BIG

From: Xueyuan Chen

Date: Fri Jul 17 2026 - 08:31:14 EST


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)
goto try_split;
redirty:
folio_mark_dirty(folio);
--
2.47.3