From: sashiko-bot@kernel.org
To: mpenttil@redhat.com, linux-mm@kvack.org
Cc: dri-devel@lists.freedesktop.org, intel-xe@lists.freedesktop.org,
"David Hildenbrand" <david@kernel.org>,
"Jason Gunthorpe" <jgg@nvidia.com>,
"Leon Romanovsky" <leonro@nvidia.com>,
"Alistair Popple" <apopple@nvidia.com>,
"Balbir Singh" <balbirs@nvidia.com>, "Zi Yan" <ziy@nvidia.com>,
"Matthew Brost" <matthew.brost@intel.com>,
"Andrew Morton" <akpm@linux-foundation.org>,
"Lorenzo Stoakes" <ljs@kernel.org>,
"Liam R. Howlett" <Liam.Howlett@oracle.com>,
"Vlastimil Babka" <vbabka@suse.cz>,
"Mike Rapoport" <rppt@kernel.org>,
"Suren Baghdasaryan" <surenb@google.com>,
"Michal Hocko" <mhocko@suse.com>, "Lyude Paul" <lyude@redhat.com>,
"Danilo Krummrich" <dakr@kernel.org>
Subject: Re: [PATCH v16 08/12] mm/hmm: implement rollback for device page migration in HMM pagewalk
Date: Thu, 22 Oct 2026 06:06:39 +0000 [thread overview]
Message-ID: <sashiko-outbox-181056@kernel.org> (raw)
In-Reply-To: <20261021060506.2377545-9-mpenttil@redhat.com>
Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
- [Critical] mm/hmm: premature rollback of migration PTEs in hmm_vma_handle_pte()
- [High] mm/hmm: incomplete rollback on mid-PMD lock drop in hmm_vma_walk_pmd()
- [High] mm/hmm: missing rollback on fault and PMD migration in hmm_vma_walk_pmd()
--
commit 5c75620371e34a43110051163d33f29ab4f700b4
Author: Mika Penttilä <mpenttil@redhat.com>
mm/hmm: implement rollback for device page migration in HMM pagewalk
This commit adds rollback handling during HMM migration page walks to unlock
and drop references on previously collected folios if page tables change while
locks are dropped.
> diff --git a/mm/hmm.c b/mm/hmm.c
> index 36a4edde9823c..5a1471fd5d288 100644
> --- a/mm/hmm.c
> +++ b/mm/hmm.c
[ ... ]
> @@ -282,6 +289,8 @@ static int hmm_vma_handle_pmd(struct mm_walk *walk, unsigned long addr,
> return hmm_record_fault(addr, end, required_fault, walk);
> }
>
> + hmm_vma_handle_migrate_prepare_rollback(hmm_vma_walk, addr,
> + end, hmm_pfns);
> pfn = pmd_pfn(pmd) + ((addr & ~PMD_MASK) >> PAGE_SHIFT);
> for (i = 0; addr < end; addr += PAGE_SIZE, i++, pfn++) {
> hmm_pfns[i] &= HMM_PFN_INOUT_FLAGS;
[Severity: High]
What happens if entries in hmm_pfns were previously collected, locks were
dropped, and on re-walk the page table entry now requires a fault, fails with
-EFAULT, or is a PMD migration entry?
In hmm_vma_handle_pmd(), if required_fault is non-zero, it returns
hmm_record_fault() before calling hmm_vma_handle_migrate_prepare_rollback().
Several other paths similarly return before rolling back previously collected
entries in range->hmm_pfns:
- hmm_vma_walk_hole() returns -EFAULT (when !walk->vma) or
hmm_record_fault() when required_fault is non-zero before reaching
hmm_pfns_fill().
- hmm_vma_handle_absent_pmd() returns hmm_record_fault() or -EFAULT when
required_fault is non-zero without calling
hmm_vma_handle_migrate_prepare_rollback().
- hmm_vma_handle_pte() jumps to the fault: label or returns -EFAULT without
rolling back *hmm_pfn.
- hmm_vma_walk_pmd() returns -EFAULT on pmd_bad(pmd) when
hmm_range_need_fault() is non-zero, and returns 0 when
thp_migration_supported() && pmd_is_migration_entry(pmd) is true with
minfo non-zero, without rolling back collected PTE entries in
hmm_pfns_start.
If hmm_record_fault() returns HMM_FAULT_PENDING while the current task still
holds folio_lock() on previously collected folios in that range, can
hmm_do_fault() -> handle_mm_fault() deadlock trying to lock the same folio, or
can the early returns leave stale collected folios locked and referenced in
range->hmm_pfns?
> @@ -412,6 +421,9 @@ static int hmm_vma_handle_pte(struct mm_walk *walk, unsigned long addr,
>
> new_pfn_flags = pte_pfn(pte) | cpu_flags;
> out:
> + hmm_vma_handle_migrate_prepare_rollback(hmm_vma_walk, addr,
> + addr + PAGE_SIZE,
> + hmm_pfn);
> *hmm_pfn = (*hmm_pfn & HMM_PFN_INOUT_FLAGS) | new_pfn_flags;
> return 0;
>
[Severity: Critical]
Could reaching the out: label in hmm_vma_handle_pte() prematurely roll back a
migration PTE that this walk already installed?
In hmm_vma_handle_pte(), when !pte_present(pte) is true, the required_fault
check runs before softleaf_is_migration(entry):
if (!pte_present(pte)) {
...
required_fault =
hmm_pte_need_fault(hmm_vma_walk, pfn_req_flags, 0);
if (!required_fault)
goto out;
...
if (softleaf_is_migration(entry)) {
if (!hmm_select_migrate(range)) {
...
return -EBUSY;
}
return 0;
}
During a migration walk without HMM_PFN_REQ_FAULT (such as migrate_vma_setup()
where range.default_flags is HMM_PFN_REQ_MIGRATE),
hmm_vma_handle_migrate_prepare() locks the folio, takes a reference, installs
a migration PTE, and marks *hmm_pfn with HMM_PFN_VALID | HMM_PFN_MIGRATE.
If the walk restarts over that range (for example, after dropping locks in
migrate_vma_split_folio() or on an -EBUSY retry), hmm_vma_handle_pte() sees
!pte_present(pte) for its own migration PTE. Because HMM_PFN_REQ_FAULT is not
set, hmm_pte_need_fault() returns 0 and jumps to out: with new_pfn_flags = 0.
At out:, hmm_vma_handle_migrate_prepare_rollback() unlocks the folio, calls
folio_put(), and clears HMM_PFN_VALID | HMM_PFN_MIGRATE from *hmm_pfn while
the migration PTE remains installed in the page table, so
remove_migration_ptes() will never be called for it.
Conversely, when HMM_PFN_REQ_FAULT is set (required_fault != 0), the
softleaf_is_migration(entry) branch returns 0 whenever
hmm_select_migrate(range) is non-zero without checking that
hmm_pfn_collected(*hmm_pfn) is true and that softleaf_to_pfn(entry) matches
the PFN in *hmm_pfn. If the migration PTE belongs to a concurrent migration
(at an uncollected slot or in a replacement PTE table), shouldn't
hmm_vma_handle_pte() roll back any mismatched *hmm_pfn and wait via
migration_entry_wait()?
[ ... ]
> @@ -1117,6 +1193,9 @@ static int hmm_vma_walk_pmd(pmd_t *pmdp,
> if (ptep) {
> lazy_mmu_mode_enable();
> hmm_vma_walk->ptelocked = true;
> + } else {
> + /* The pte table is gone */
> + hmm_vma_handle_migrate_prepare_rollback(walk->private, addr, end, hmm_pfns);
> }
> } else {
> ptep = pte_offset_map(pmdp, addr);
[Severity: High]
Does this rollback miss entries collected in [start, addr) when the PTE lock
is dropped partway through a PMD?
In hmm_vma_walk_pmd(), the PTE loop advances addr and hmm_pfns from start
toward end while collecting folios into hmm_pfns_start. If
hmm_vma_handle_migrate_prepare() hits a large folio at addr > start,
migrate_vma_split_folio() drops the PTE lock and returns -EAGAIN, and
hmm_vma_walk_pmd() jumps to again: without resetting addr = start:
again:
hmm_pfns = &range->hmm_pfns[(addr - range->start) >> PAGE_SHIFT];
...
if (minfo) {
ptep = pte_offset_map_lock(mm, pmdp, addr, &hmm_vma_walk->ptl);
if (ptep) {
lazy_mmu_mode_enable();
hmm_vma_walk->ptelocked = true;
} else {
/* The pte table is gone */
hmm_vma_handle_migrate_prepare_rollback(walk->private, addr, end, hmm_pfns);
}
}
if (!ptep) {
addr = start;
goto again;
}
When ptep is NULL at addr > start, hmm_vma_handle_migrate_prepare_rollback()
is called with addr and hmm_pfns before addr is reset to start, so it only
scans the uncollected tail [addr, end) and leaves folios collected in
[start, addr) (at hmm_pfns_start) locked and referenced.
In addition, if the PTE table was cleared and replaced by another PTE table
while the lock was dropped in migrate_vma_split_folio() (or during a mid-PMD
fault where hmm_record_fault() sets hmm_vma_walk->last = addr),
pte_offset_map_lock() succeeds at addr > start on the new PTE table and resumes
from addr without re-walking or rolling back [start, addr). Should mid-PMD lock
drops restart from start (with hmm_pfns_start) so that [start, addr) is
re-validated?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261021060506.2377545-1-mpenttil@redhat.com?part=8
next prev parent reply other threads:[~2026-10-22 6:06 UTC|newest]
Thread overview: 33+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-21 6:04 [PATCH v16 00/12] migrate on fault for device pages mpenttil
2026-10-21 6:04 ` [PATCH v16 01/12] mm/Kconfig: changes for " mpenttil
2026-10-21 6:04 ` [PATCH v16 02/12] mm: add helper to convert HMM pfn to migrate pfn mpenttil
2026-10-21 6:04 ` [PATCH v16 03/12] mm/hmm: preparations for HMM to participate in migration mpenttil
2026-10-21 7:17 ` Balbir Singh
2026-10-21 8:11 ` Mika Penttilä
2026-10-22 6:06 ` sashiko-bot
2026-10-21 6:04 ` [PATCH v16 04/12] mm/hmm: do the plumbing " mpenttil
2026-10-22 6:06 ` sashiko-bot
2026-10-21 6:04 ` [PATCH v16 05/12] mm/hmm: migrate collection in HMM pagewalk - pte level mpenttil
2026-10-21 6:56 ` Balbir Singh
2026-10-21 7:09 ` Mika Penttilä
2026-10-22 6:06 ` sashiko-bot
2026-10-21 6:05 ` [PATCH v16 06/12] mm/hmm: migrate collection in HMM pagewalk - pmd level mpenttil
2026-10-22 6:06 ` sashiko-bot
2026-10-21 6:05 ` [PATCH v16 07/12] mm/hmm: add lazy MMU mode support for migration in HMM pagewalk mpenttil
2026-10-21 6:05 ` [PATCH v16 08/12] mm/hmm: implement rollback for device page " mpenttil
2026-10-22 6:06 ` sashiko-bot [this message]
2026-10-21 6:05 ` [PATCH v16 09/12] mm: enable device page migration from " mpenttil
2026-10-21 6:19 ` Balbir Singh
2026-10-21 6:30 ` Mika Penttilä
2026-10-22 6:06 ` sashiko-bot
2026-10-21 6:05 ` [PATCH v16 10/12] lib/test_hmm: add a new testcase for the migrate on fault mpenttil
2026-10-22 6:06 ` sashiko-bot
2026-10-21 6:05 ` [PATCH v16 11/12] Documentation/mm/hmm: document migration through hmm_range_fault() mpenttil
2026-10-22 6:06 ` sashiko-bot
2026-10-21 6:05 ` [PATCH v16 12/12] drm/nouveau/svm: add support for migrate on fault mpenttil
2026-10-22 6:06 ` sashiko-bot
2026-10-21 6:50 ` ✗ CI.checkpatch: warning for Migrate on fault for device pages (rev8) Patchwork
2026-10-21 6:53 ` ✓ CI.KUnit: success " Patchwork
2026-10-21 7:09 ` ✗ CI.checksparse: warning " Patchwork
2026-10-21 7:29 ` ✓ Xe.CI.BAT: success " Patchwork
2026-10-21 9:50 ` ✗ Xe.CI.FULL: failure " Patchwork
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=sashiko-outbox-181056@kernel.org \
--to=sashiko-bot@kernel.org \
--cc=Liam.Howlett@oracle.com \
--cc=akpm@linux-foundation.org \
--cc=apopple@nvidia.com \
--cc=balbirs@nvidia.com \
--cc=dakr@kernel.org \
--cc=david@kernel.org \
--cc=dri-devel@lists.freedesktop.org \
--cc=intel-xe@lists.freedesktop.org \
--cc=jgg@nvidia.com \
--cc=leonro@nvidia.com \
--cc=linux-mm@kvack.org \
--cc=ljs@kernel.org \
--cc=lyude@redhat.com \
--cc=matthew.brost@intel.com \
--cc=mhocko@suse.com \
--cc=mpenttil@redhat.com \
--cc=rppt@kernel.org \
--cc=sashiko-reviews@lists.linux.dev \
--cc=surenb@google.com \
--cc=vbabka@suse.cz \
--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