From: "Garg, Shivank" <shivankg@amd.com>
To: "lance.yang@linux.dev" <lance.yang@linux.dev>,
"ying.huang@linux.alibaba.com" <ying.huang@linux.alibaba.com>
Cc: "Rao, Bharata Bhasker" <bharata@amd.com>,
"rppt@kernel.org" <rppt@kernel.org>,
"weixugc@google.com" <weixugc@google.com>,
"byungchul@sk.com" <byungchul@sk.com>,
"rakie.kim@sk.com" <rakie.kim@sk.com>,
"vbabka@kernel.org" <vbabka@kernel.org>,
"harry@kernel.org" <harry@kernel.org>,
"rientjes@google.com" <rientjes@google.com>,
"riel@surriel.com" <riel@surriel.com>,
"akpm@linux-foundation.org" <akpm@linux-foundation.org>,
"david@kernel.org" <david@kernel.org>,
"matthew.brost@intel.com" <matthew.brost@intel.com>,
"surenb@google.com" <surenb@google.com>,
"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
"kinseyho@google.com" <kinseyho@google.com>,
"dev.jain@arm.com" <dev.jain@arm.com>,
"gourry@gourry.net" <gourry@gourry.net>,
"ziy@nvidia.com" <ziy@nvidia.com>,
"linux-mm@kvack.org" <linux-mm@kvack.org>,
"jannh@google.com" <jannh@google.com>,
"liam@infradead.org" <liam@infradead.org>,
"linmiaohe@huawei.com" <linmiaohe@huawei.com>,
"mhocko@suse.com" <mhocko@suse.com>,
"ljs@kernel.org" <ljs@kernel.org>,
"kmanaouil.dev@gmail.com" <kmanaouil.dev@gmail.com>,
"joshua.hahnjy@gmail.com" <joshua.hahnjy@gmail.com>,
"apopple@nvidia.com" <apopple@nvidia.com>,
"fvdl@google.com" <fvdl@google.com>
Subject: Re: [PATCH v2 7/7] mm/rmap: batch the unmap of large folios in try_to_migrate_one()
Date: Wed, 19 Aug 2026 10:09:10 +0000 [thread overview]
Message-ID: <827e1126c02485b3d6de5f28027a75262b6c7076.camel@amd.com> (raw)
In-Reply-To: <87tsoq5tvq.fsf@DESKTOP-5N7EMDA>
On Wed, 2026-08-19 at 17:42 +0800, Huang, Ying wrote:
> Lance Yang <lance.yang@linux.dev> writes:
>
> > On Tue, Aug 18, 2026 at 04:55:06PM +0800, Miaohe Lin wrote:
> > > On 2026/8/17 17:14, Lance Yang wrote:
> > > > +Cc Miaohe
> > > >
> > > > On Thu, Aug 13, 2026 at 04:23:18AM +0000, Shivank Garg wrote:
> > > > > try_to_migrate_one() converts present PTEs to migration entries one at a
> > > > > time. For a PTE-mapped large folio, this repeat calls to ptep clear+flush,
> > > > > the migration entry build and set, folio_remove_rmap_pte() and folio_put(),
> > > > > each re-entering page_vma_mapped_walk() once per base page (256 times for
> > > > > 1M folio).
> > > > >
> > > > > Mirror try_to_unmap_one() to introduce folio_migrate_pte_batch() to detect
> > > > > eligible batch for PTEs mapping conseuctive subpages of a large folios,
> > > > > and convert the whole batch in one shot using the batched helpers.
> > > > >
> > > > > A side-effect of this change is trace_set_migration_pte() will record
> > > > > one event per batched run instead of earlier behavior of one per base page.
> > > > >
> > > > > Signed-off-by: Shivank Garg <shivankg@amd.com>
> > > > > ---
> > > > > mm/rmap.c | 115 ++++++++++++++++++++++++++++++++++++++++++++++----------------
> > > > > 1 file changed, 86 insertions(+), 29 deletions(-)
> > > > >
> > > > > diff --git a/mm/rmap.c b/mm/rmap.c
> > > > > index 35752a70f3a0..63b885c0b7ef 100644
> > > > > --- a/mm/rmap.c
> > > > > +++ b/mm/rmap.c
> > > > > @@ -2675,6 +2675,44 @@ static bool try_to_migrate_hugetlb_one(struct folio *folio,
> > > > > return ret;
> > > > > }
> > > > >
> > > > > +static inline unsigned int folio_migrate_pte_batch(struct folio *folio,
> > > > > + struct page_vma_mapped_walk *pvmw, pte_t pte,
> > > > > + struct page *subpage, bool anon_exclusive)
> > > > > +{
> > > > > + unsigned long end_addr, addr = pvmw->address;
> > > > > + struct vm_area_struct *vma = pvmw->vma;
> > > > > + unsigned int max_nr, nr;
> > > > > +
> > > > > +#ifdef __HAVE_ARCH_UNMAP_ONE
> > > > > + /* Cannot batch unmap if arch_unmap_one() is defined. */
> > > > > + return 1;
> > > > > +#endif
> > > > > +
> > > > > + if (!folio_test_large(folio))
> > > > > + return 1;
> > > > > + if (folio_is_zone_device(folio) || folio_test_has_hwpoisoned(folio))
> > > > > + return 1;
> > > > > + if (pte_unused(pte))
> > > > > + return 1;
> > > > > +
> > > > > + /* We may only batch within a single VMA and a single page table. */
> > > > > + end_addr = pmd_addr_end(addr, vma->vm_end);
> > > > > + max_nr = (end_addr - addr) >> PAGE_SHIFT;
> > > >
> > > > Hmm ... can this still batch over a poisoned tail page?
> > > >
> > > > memory_failure() sets PageHWPoison() before taking folio lock, but
> > > > cannot set PG_has_hwpoisoned until it acquires and releases that lock.
> > > >
> > > > So tail page can already be poisoned while folio_test_has_hwpoisoned()
> > > > still returns false ... no?
> > >
> > > When memory error hits thp pages, memory_failure() first set PG_has_hwpoisoned and
> > > then tries to split thp pages. And try_to_migrate() will be called to set migration
> > > entries for anon pages. Does folio_migrate_pte_batch() work on this case? If so, the
> > > folio_test_has_hwpoisoned() check above could catch the bad pages?
> > >
> > > Or do you worry about the scene that meory error hits a thp while it's under migration?
> >
> > Yeah, latter case is exactly what I meant.
> >
> > try_to_migrate() is called with folio lock held. If migration already
> > owns the lock, memory_failure() can set PageHWPoison() on a tail page and
> > then block in folio_lock(), before reaching folio_set_has_hwpoisoned().
> > try_to_migrate_one() may meanwhile start from a healthy subpage, see
> > PageHWPoison(subpage) clear and PG_has_hwpoisoned still clear, then batch
> > across poisoned tail and install a normal migration entry for it.
> >
> > Once memory_failure() publishes PG_has_hwpoisoned, the folio-level check
> > does stop batching, as you said. It's just this window before publication
> > that worries me ...
>
> I agree with you that we should check PageHWPoison() for each subpage
> before batching.
>
> However, IIUC, your suggestion can only reduce the race window instead
> of avoiding it completely. PageHWPoison() may be set even after checking
> it anyway.
>
Thank you Lance, Miaohe, Ying for your analysis.
I agree on it.
In my understanding, following happens:
Even before memory_failure() takes folio lock, it takes folio reference.
memory_failure() -> get_hwpoison_page() -> bump the refcount
Now,
__migrate_folio() checks for:
folio_ref_count(src) != folio_expected_ref_count(src) + 1
This would abort the migration.
Even if it pass that window, folio_mc_copy() does machine-check safe copy
and would catch the poison and return -EHWPOISON.
So, this limits the consequences.
For correctness, I'll have poison check for each subpage in
folio_migrate_pte_batch().
Thanks,
Shivank
> >
prev parent reply other threads:[~2026-08-19 10:09 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-13 4:23 [PATCH v2 0/7] mm: batch rmap walks during large folio migration Shivank Garg
2026-08-13 4:23 ` [PATCH v2 1/7] mm: factor out generic PTE batch detection from swap_pte_batch() Shivank Garg
2026-08-13 9:57 ` David Hildenbrand (Arm)
2026-08-14 8:00 ` Garg, Shivank
2026-08-16 7:48 ` Garg, Shivank
2026-08-13 4:23 ` [PATCH v2 2/7] mm/migrate: factor out migration PTE construction Shivank Garg
2026-08-13 4:23 ` [PATCH v2 3/7] mm/migrate: split remove_migration_pte_hugetlb() out of remove_migration_pte() Shivank Garg
2026-08-19 11:24 ` Karim Manaouil
2026-08-19 17:49 ` Garg, Shivank
2026-08-13 4:23 ` [PATCH v2 4/7] mm/migrate: batch the restore-side migration rmap walk Shivank Garg
2026-08-13 4:23 ` [PATCH v2 5/7] mm/rmap: factor out migration PTE construction Shivank Garg
2026-08-13 4:23 ` [PATCH v2 6/7] mm/rmap: split try_to_migrate_hugetlb_one() out of try_to_migrate_one() Shivank Garg
2026-08-13 4:23 ` [PATCH v2 7/7] mm/rmap: batch the unmap of large folios in try_to_migrate_one() Shivank Garg
2026-08-17 9:14 ` Lance Yang
2026-08-18 8:55 ` Miaohe Lin
2026-08-18 9:20 ` Lance Yang
2026-08-19 9:05 ` Miaohe Lin
2026-08-19 9:42 ` Huang, Ying
2026-08-19 9:57 ` Lance Yang
2026-08-19 10:09 ` Garg, Shivank [this message]
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=827e1126c02485b3d6de5f28027a75262b6c7076.camel@amd.com \
--to=shivankg@amd.com \
--cc=akpm@linux-foundation.org \
--cc=apopple@nvidia.com \
--cc=bharata@amd.com \
--cc=byungchul@sk.com \
--cc=david@kernel.org \
--cc=dev.jain@arm.com \
--cc=fvdl@google.com \
--cc=gourry@gourry.net \
--cc=harry@kernel.org \
--cc=jannh@google.com \
--cc=joshua.hahnjy@gmail.com \
--cc=kinseyho@google.com \
--cc=kmanaouil.dev@gmail.com \
--cc=lance.yang@linux.dev \
--cc=liam@infradead.org \
--cc=linmiaohe@huawei.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=ljs@kernel.org \
--cc=matthew.brost@intel.com \
--cc=mhocko@suse.com \
--cc=rakie.kim@sk.com \
--cc=riel@surriel.com \
--cc=rientjes@google.com \
--cc=rppt@kernel.org \
--cc=surenb@google.com \
--cc=vbabka@kernel.org \
--cc=weixugc@google.com \
--cc=ying.huang@linux.alibaba.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.