Re: [PATCH v2 2/4] mm/mlock: wait for migration to finish when mlocking a folio

From: sashiko-bot

Date: Tue Jul 07 2026 - 09:24:19 EST


Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] Returning ACTION_AGAIN from the PTE loop causes double-counting of folio mlock_count, permanently stranding folios on the unevictable list.
--

--- Patch [2]: [PATCH v2 2/4] mm/mlock: wait for migration to finish when mlocking a folio ---
commit 5e064939ab68367720d5bb81c64aebdb067992b6
Author: Wandun Chen <chenwandun@xxxxxxxxxxx>

mm/mlock: wait for migration to finish when mlocking a folio

This commit modifies mlock to wait for migration entries when
compaction_allow_unevictable is false. This prevents spike latency in
RT kernels caused by page faults waiting on migration after mlocking.

Link: https://lore.kernel.org/lkml/c8793c0f-7156-4cb7-9e6e-7909397e2fff@xxxxxxxxxx/#t

> diff --git a/mm/mlock.c b/mm/mlock.c
> index 97e49038d8d33..ac65de40b22b9 100644
> --- a/mm/mlock.c
> +++ b/mm/mlock.c

[ ... ]

> @@ -383,8 +393,17 @@ static int mlock_pte_range(pmd_t *pmd, unsigned long addr,
>
> for (pte = start_pte; addr != end; pte++, addr += PAGE_SIZE) {
> ptent = ptep_get(pte);
> - if (!pte_present(ptent))
> + if (!pte_present(ptent)) {
> + if (unlikely((vma->vm_flags & VM_LOCKED) &&
> + !compaction_allow_unevictable() &&
> + softleaf_is_migration(softleaf_from_pte(ptent)))) {
> + pte_unmap_unlock(start_pte, ptl);
> + migration_entry_wait(vma->vm_mm, pmd, addr);
> + walk->action = ACTION_AGAIN;
> + return 0;

[Severity: High]
Does returning ACTION_AGAIN from within the PTE loop cause mlock_count to be
inflated for previously processed PTEs?

If the loop processes some present PTEs (calling mlock_folio() on them) and
then encounters a migration entry, it returns ACTION_AGAIN. This causes the
generic page table walker to restart the callback from the original PMD start
address:

mm/pagewalk.c:walk_pmd_range() {
again:
...
if (ops->pmd_entry)
err = ops->pmd_entry(pmd, addr, next, walk);
if (err)
break;

if (walk->action == ACTION_AGAIN)
goto again;
...
}

Because addr was not advanced in walk_pmd_range(), mlock_pte_range() will
process the earlier PTEs a second time, incrementing folio->mlock_count again.
When the VMA is later unmapped, mlock_count will never reach zero, permanently
stranding these folios on the unevictable list and leaking memory.

> + }
> continue;
> + }
> folio = vm_normal_folio(vma, addr, ptent);
> if (!folio || folio_is_zone_device(folio))
> continue;

--
Sashiko AI review · https://sashiko.dev/#/patchset/20260707125925.3725177-1-chenwandun1@xxxxxxxxx?part=2