[PATCH v1 1/3] mm/memfd_luo: optimize shmem_recalc_inode calls in retrieve path
From: Chenghao Duan
Date: Wed Mar 18 2026 - 21:30:59 EST
Move shmem_recalc_inode() out of the loop in memfd_luo_retrieve_folios()
to improve performance when restoring large memfds.
Currently, shmem_recalc_inode() is called for each folio during restore,
which is O(n) expensive operations. This patch collects the number of
successfully added folios and calls shmem_recalc_inode() once after the
loop completes, reducing complexity to O(1).
Additionally, fix the error path to also call shmem_recalc_inode() for
the folios that were successfully added before the error occurred.
Signed-off-by: Chenghao Duan <duanchenghao@xxxxxxxxxx>
---
mm/memfd_luo.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/mm/memfd_luo.c b/mm/memfd_luo.c
index b8edb9f981d7..5ddd3657d8be 100644
--- a/mm/memfd_luo.c
+++ b/mm/memfd_luo.c
@@ -397,6 +397,7 @@ static int memfd_luo_retrieve_folios(struct file *file,
struct folio *folio;
int err = -EIO;
long i;
+ u64 nr_added = 0;
for (i = 0; i < nr_folios; i++) {
const struct memfd_luo_folio_ser *pfolio = &folios_ser[i];
@@ -448,12 +449,15 @@ static int memfd_luo_retrieve_folios(struct file *file,
goto unlock_folio;
}
- shmem_recalc_inode(inode, 1, 0);
+ nr_added++;
folio_add_lru(folio);
folio_unlock(folio);
folio_put(folio);
}
+ if (nr_added)
+ shmem_recalc_inode(inode, nr_added, 0);
+
return 0;
unlock_folio:
@@ -472,6 +476,9 @@ static int memfd_luo_retrieve_folios(struct file *file,
folio_put(folio);
}
+ if (nr_added)
+ shmem_recalc_inode(inode, nr_added, 0);
+
return err;
}
--
2.25.1