Re: [PATCH v1 1/3] mm/memfd_luo: optimize shmem_recalc_inode calls in retrieve path

From: Pasha Tatashin

Date: Thu Mar 19 2026 - 11:34:11 EST


On Wed, Mar 18, 2026 at 9:29 PM Chenghao Duan <duanchenghao@xxxxxxxxxx> wrote:
>
> 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;

nit: I perfer RCT for local variables order, but it is not followed in
this file anyway.

>
> 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);
> +

Reviewed-by: Pasha Tatashin <pasha.tatashin@xxxxxxxxxx>