Linux-mm Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Pratyush Yadav <pratyush@kernel.org>
To: Pasha Tatashin <pasha.tatashin@soleen.com>
Cc: Pratyush Yadav <pratyush@kernel.org>,
	 Alexander Viro <viro@zeniv.linux.org.uk>,
	 Christian Brauner <brauner@kernel.org>,  Jan Kara <jack@suse.cz>,
	 "Matthew Wilcox (Oracle)" <willy@infradead.org>,
	Hugh Dickins <hughd@google.com>,
	 Baolin Wang <baolin.wang@linux.alibaba.com>,
	 Andrew Morton <akpm@linux-foundation.org>,
	 David Hildenbrand <david@kernel.org>,  Zi Yan <ziy@nvidia.com>,
	 "Liam R. Howlett" <liam@infradead.org>,
	 Nico Pache <nico.pache@linux.dev>,
	 Ryan Roberts <ryan.roberts@arm.com>,
	 Dev Jain <dev.jain@arm.com>,  Barry Song <baohua@kernel.org>,
	 Lance Yang <lance.yang@linux.dev>,
	 Usama Arif <usama.arif@linux.dev>,
	 Kiryl Shutsemau <kas@kernel.org>,
	 Mike Rapoport <rppt@kernel.org>,
	 Matthew Brost <matthew.brost@intel.com>,
	 Joshua Hahn <joshua.hahnjy@gmail.com>,
	Byungchul Park <byungchul@sk.com>,
	 Gregory Price <gourry@gourry.net>,
	Ying Huang <ying.huang@linux.alibaba.com>,
	 Alistair Popple <apopple@nvidia.com>,
	 Kairui Song <kasong@tencent.com>,  Qi Zheng <qi.zheng@linux.dev>,
	 Shakeel Butt <shakeel.butt@linux.dev>,
	 Axel Rasmussen <axelrasmussen@google.com>,
	 Yuanchu Xie <yuanchu@google.com>, Wei Xu <weixugc@google.com>,
	 Baoquan He <baoquan.he@linux.dev>,
	Johannes Weiner <hannes@cmpxchg.org>,
	 Michal Hocko <mhocko@kernel.org>,
	Lorenzo Stoakes <ljs@kernel.org>,
	 linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org,
	 linux-mm@kvack.org, kexec@lists.infradead.org
Subject: Re: [PATCH 1/3] mm/memfd_luo: don't use memfd_pin_folios()
Date: Thu, 29 Oct 2026 00:04:03 +0100	[thread overview]
Message-ID: <2vxz4ie5o2ak.fsf@kernel.org> (raw)
In-Reply-To: <179321872100.1775665.6881420026761127422.b4-review@b4> (Pasha Tatashin's message of "Wed, 28 Oct 2026 16:18:41 -0400")

On Wed, Oct 28 2026, Pasha Tatashin wrote:

>> memfd_luo takes a snapshot of the folios in the file's mapping. To make
>> sure the snapshot does not go out of sync, it pins the folios in the
>> file via memfd_pin_folios(). The pinning also migrates the folios out of
>> MIGRATE_MOVABLE to make sure doesn't land in KHO boot memory or in a CMA
>> region.
>> 
>> memfd_pin_folios() does not lock the folios. So it can race with
>> shmem_writeout(). A folio returned by memfd_pin_folios() might already
>> be in swap cache. This happens to work but is fragile. memfd_luo looks
>> at folio flags and index on a folio that isn't in the memfd's page
>> cache.
>> 
>> In addition, memfd_pin_folios() needs the caller to allocate an array of
>> folios. memfd_luo does not really need that since it will vmalloc
>> folios_ser and store the information there anyway. The folios array is
>> unnecessary overhead.
>> 
>> Finally, memfd_pin_folios() fills in holes in the memfd. This makes
>> preserving sparse memfds very expensive in both compute and memory.
>> While this patch doesn't yet stop filling in the holes, it sets up the
>> infrastructure to make it simpler.
>
> +1, this is problematic and should be resolved. In some setups, VMMs 
> leave holes for PCI/IO space; with the current approach, single memfd 
> preservation does not work for such use cases.

Yep, agreed. There are a couple parts to this. First is this patch. Next
is KHO xarray. The patchset is ready, I'll send it after -rc1.

I think I will move this patch to that series and then make the series
also support holes.

>
>> Fix all this by walking the page cache directly using shmem_get_folio()
>> with SGP_CACHE. This returns a locked folio with an elevated refcount.
>> memfd_luo holds that reference until the memfd is unpreserved. This
>> blocks compaction, migration, etc.
>> 
>> There is still a need to migrate folios out of MIGRATE_MOVABLE page
>> blocks. This is because those might be CMA or KHO scratch. memfd_luo
>> will hold a longterm reference to the folios so it will block migration
>> in that pageblock. Introduce memfd_luo_migrate_folio() to do this.
>> 
>> Also factor out folio unpreservation logic into memfd_luo_put_folios()
>> and use it from memfd_luo_unpreserve_folios() and from error paths in
>> memfd_luo_preserve_folios().
>> 
>> Since shmem_get_folio() always returns uptodate folios, drop the folio
>> zeroing logic.
>> 
>> This change also improves preservation performance, shown in the table
>> below.
>> 
>> |------------------+----------+------------+-------|
>> | memfd            | baseline | this patch | delta |
>> |------------------+----------+------------+-------|
>> | 4K pages, 32 GiB | 748 ms   | 600 ms     |  -20% |
>> | THP, 4 GiB       | 0.59 ms  | 0.59 ms    |    0% |
>> | THP, 16 GiB      | 2.99 ms  | 2.61 ms    |  -13% |
>> | THP, 32 GiB      | 4.83 ms  | 5.21 ms    |   +8% |
>> | sparse, 32 GiB   | 8695 ms  | 7269 ms    |  -16% |
>> |------------------+----------+------------+-------|
>
> For THP 16 GiB / 32 GiB, the -13% / +8% swings look like high run-to-run 
> variance. However, maybe not: is it because vmalloc_array() is 
> overallocating memory for folios_ser?

Could be, I only did a handful of runs. But I also reckon this is
vmalloc_array() over-allocating. It over-allocated before this patch
too, for the folios array, but that allocation was half as big since
folios_ser is 16 bytes each.

>
> Also, could you clarify what "sparse, 32 GiB" means in this benchmark? 
> Was the memfd completely unfaulted before preserve (so preserve faults 
> in all 4K pages), or partially populated?

It was completely unfaulted. Size was set via ftruncate() and then
preserved. So it is the worse case of "sparse".

[...]
>> @@ -113,99 +213,77 @@ static int memfd_luo_preserve_folios(struct file *file,
>>  	 * Guess the number of folios based on inode size. Real number might end
>>  	 * up being smaller if there are higher order folios.
>>  	 */
>> -	max_folios = PAGE_ALIGN(size) / PAGE_SIZE;
>> -	folios = kvmalloc_objs(*folios, max_folios);
>> -	if (!folios)
>> +	end = DIV_ROUND_UP_ULL(size, PAGE_SIZE);
>> +	max_folios = end;
>> +	folios_ser = vmalloc_array(max_folios, sizeof(*folios_ser));
>> +	if (!folios_ser)
>>  		return -ENOMEM;
>
> I bet in practice memfds almost always contain folios of the same size, 
> so why not estimate the folios_ser size based on the first folio's 
> order, and only if that ends up being too small, vrealloc() to match the 
> maximum possible remaining size?

That's a good idea! But I think the switch to KHO Xarray will remove the
need for this.

>
> It would be a different change though.
>
[...]
>> +
>> +		if (unlikely(!folio_is_longterm_pinnable(folio))) {
>> +			folio_unlock(folio);
>> +			err = memfd_luo_migrate_folio(folio);
>> +			/* Someone else might have it isolated, retry a bit. */
>> +			if (err == -EBUSY && ++busy_retries < MEMFD_LUO_MIGRATE_RETRIES)
>> +				continue;
>> +			if (err)
>> +				goto err_restore;
>> +			continue;
>>  		}
>
> Nit:
>
> I would suggest adding another helper, memfd_luo_get_folio(inode, index, 
> &folio), that wraps:
>
> - shmem_get_folio()
> - The !folio_is_longterm_pinnable() migration retry loop logic
>
> I think this would make the final code a bit more manageable.

Sounds good, will do.

>
> Other than that the patch looks alright, feel free to add
> Acked-by: Pasha Tatashin <pasha.tatashin@soleen.com>
> Once the nit is addressed.

Thanks!

I think the MM side might take some time to gather reviews so I will
send this out as part of a liveupdate-only series. This patch is useful
on its own anyway.

-- 
Regards,
Pratyush Yadav


  reply	other threads:[~2026-10-28 23:04 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-27 17:30 [PATCH 0/3] mm: allow freezing mappings Pratyush Yadav
2026-10-27 17:30 ` [PATCH 1/3] mm/memfd_luo: don't use memfd_pin_folios() Pratyush Yadav
2026-10-28 20:18   ` Pasha Tatashin
2026-10-28 23:04     ` Pratyush Yadav [this message]
2026-10-29  0:01       ` Pasha Tatashin
2026-10-29 13:15         ` Pratyush Yadav
2026-10-27 17:30 ` [PATCH 2/3] mm: allow freezing i_pages Pratyush Yadav
2026-10-28 17:31   ` sashiko-bot
2026-10-27 17:30 ` [PATCH 3/3] mm: shmem: use mapping_set_frozen() for memfd preservation Pratyush Yadav
2026-10-28 17:31   ` sashiko-bot
2026-10-27 17:35 ` [PATCH 0/3] mm: allow freezing mappings David Hildenbrand (Arm)
2026-10-27 17:38   ` Pratyush Yadav
2026-10-27 18:59     ` David Hildenbrand (Arm)

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=2vxz4ie5o2ak.fsf@kernel.org \
    --to=pratyush@kernel.org \
    --cc=akpm@linux-foundation.org \
    --cc=apopple@nvidia.com \
    --cc=axelrasmussen@google.com \
    --cc=baohua@kernel.org \
    --cc=baolin.wang@linux.alibaba.com \
    --cc=baoquan.he@linux.dev \
    --cc=brauner@kernel.org \
    --cc=byungchul@sk.com \
    --cc=david@kernel.org \
    --cc=dev.jain@arm.com \
    --cc=gourry@gourry.net \
    --cc=hannes@cmpxchg.org \
    --cc=hughd@google.com \
    --cc=jack@suse.cz \
    --cc=joshua.hahnjy@gmail.com \
    --cc=kas@kernel.org \
    --cc=kasong@tencent.com \
    --cc=kexec@lists.infradead.org \
    --cc=lance.yang@linux.dev \
    --cc=liam@infradead.org \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=ljs@kernel.org \
    --cc=matthew.brost@intel.com \
    --cc=mhocko@kernel.org \
    --cc=nico.pache@linux.dev \
    --cc=pasha.tatashin@soleen.com \
    --cc=qi.zheng@linux.dev \
    --cc=rppt@kernel.org \
    --cc=ryan.roberts@arm.com \
    --cc=shakeel.butt@linux.dev \
    --cc=usama.arif@linux.dev \
    --cc=viro@zeniv.linux.org.uk \
    --cc=weixugc@google.com \
    --cc=willy@infradead.org \
    --cc=ying.huang@linux.alibaba.com \
    --cc=yuanchu@google.com \
    --cc=ziy@nvidia.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox