All of lore.kernel.org
 help / color / mirror / Atom feed
From: "David Hildenbrand (arm)" <david@kernel.org>
To: Zi Yan <ziy@nvidia.com>
Cc: Wei Yang <richard.weiyang@gmail.com>,
	akpm@linux-foundation.org, lorenzo.stoakes@oracle.com,
	riel@surriel.com, Liam.Howlett@oracle.com, vbabka@suse.cz,
	harry.yoo@oracle.com, jannh@google.com, gavinguo@igalia.com,
	baolin.wang@linux.alibaba.com, linux-mm@kvack.org,
	Lance Yang <lance.yang@linux.dev>,
	stable@vger.kernel.org
Subject: Re: [Patch v2] mm/huge_memory: fix early failure try_to_migrate() when split huge pmd for shared thp
Date: Wed, 4 Feb 2026 21:43:42 +0100	[thread overview]
Message-ID: <df86ccfd-68a5-416e-81cc-02858e395b70@kernel.org> (raw)
In-Reply-To: <E4DA2E02-DE3B-4D26-A427-5D53FCA36A58@nvidia.com>

On 2/4/26 21:02, Zi Yan wrote:
> On 4 Feb 2026, at 14:36, David Hildenbrand (arm) wrote:
> 
>> Sorry for the late reply. I saw that I was CCed in v1 but I am only now catching up with mails ... slowly but steadily.
>>
>>> Without the above commit, we can successfully split to order 0.
>>> With the above commit, the folio is still a large folio.
>>>
>>> The reason is the above commit return false after split pmd
>>> unconditionally in the first process and break try_to_migrate().
>>>
>>> The tricky thing in above reproduce method is current debugfs interface
>>> leverage function split_huge_pages_pid(), which will iterate the whole
>>> pmd range and do folio split on each base page address. This means it
>>> will try 512 times, and each time split one pmd from pmd mapped to pte
>>> mapped thp. If there are less than 512 shared mapped process,
>>> the folio is still split successfully at last. But in real world, we
>>> usually try it for once.
>>
>> Ah, that explains magic number 513.
>>
>>>
>>> This patch fixes this by restart page_vma_mapped_walk() after
>>> split_huge_pmd_locked(). Because split_huge_pmd_locked() may fall back to
>>> (freeze = false) if folio_try_share_anon_rmap_pmd() fails and the PMD is
>>> just split instead of split to migration entry.
>>
>> Right, but folio_try_share_anon_rmap_pmd() should never fail on the folios that have already been shared? (above you write that it is shared with 512 children)
>>
>> The only case where  folio_try_share_anon_rmap_pmd() could fail would be if the folio would not be shared, and there would only be a single PMD then, so there is nothing you can do -> abort.
>>
>> Returning "false" from try_to_migrate_one() is the real issue, as it makes rmap_walk_anon() to just stop -> abort the walk.
>>
>>
>> So I suspect v1 was actually sufficient, or what am I missing where the restart would actually be required?
> 
> The explanation is not for the shared case mentioned above. It is for unshared
> folio. If an unshared folio’s PAE cannot be cleared, try_to_migrate_one() return
> true, indicating a success.

Oh. You mean that should be something like

"This patch fixes this by restart page_vma_mapped_walk() after 
split_huge_pmd_locked(). We cannot simply return "true" to fix the 
problem, as that would affect another case: 
split_huge_pmd_locked()->folio_try_share_anon_rmap_pmd() can failed and 
leave the folio mapped through PTEs; we would return "true" from 
try_to_migrate_one() in that case as well. While that is mostly 
harmless, we could end up walking the rmap, wasting some cycles.".


> Yeah, since it is an unshared folio, the return
> value of try_to_migrate_one() does not matter. This fix makes try_to_migrate_one()
> return false.

Right, it's not really problematic. We could end up walking the rmap and 
burn some cycles.

> 
>>
>>
>> (maybe we should get rid of the usage of booleans here at some point, an enum like abort/continue would have been much clearer)
>>
>>> Restart
>>> page_vma_mapped_walk() and let try_to_migrate_one() try on each PTE
>>> again and fail try_to_migrate() early if it fails.
>>>
>>> Signed-off-by: Wei Yang <richard.weiyang@gmail.com>
>>> Fixes: 60fbb14396d5 ("mm/huge_memory: adjust try_to_migrate_one() and split_huge_pmd_locked()")
>>> Cc: Gavin Guo <gavinguo@igalia.com>
>>> Cc: "David Hildenbrand (Red Hat)" <david@kernel.org>
>>> Cc: Zi Yan <ziy@nvidia.com>
>>> Cc: Baolin Wang <baolin.wang@linux.alibaba.com>
>>> Cc: Lance Yang <lance.yang@linux.dev>
>>> Cc: <stable@vger.kernel.org>
>>>
>>> ---
>>> v2:
>>>     * restart page_vma_mapped_walk() after split_huge_pmd_locked()
>>> ---
>>>    mm/rmap.c | 11 ++++++++---
>>>    1 file changed, 8 insertions(+), 3 deletions(-)
>>>
>>> diff --git a/mm/rmap.c b/mm/rmap.c
>>> index 618df3385c8b..5b853ec8901d 100644
>>> --- a/mm/rmap.c
>>> +++ b/mm/rmap.c
>>> @@ -2446,11 +2446,16 @@ static bool try_to_migrate_one(struct folio *folio, struct vm_area_struct *vma,
>>>    			__maybe_unused pmd_t pmdval;
>>>     			if (flags & TTU_SPLIT_HUGE_PMD) {
>>> +				/*
>>> +				 * After split_huge_pmd_locked(), restart the
>>> +				 * walk to detect PageAnonExclusive handling
>>> +				 * failure in __split_huge_pmd_locked().
>>> +				 */
>>>    				split_huge_pmd_locked(vma, pvmw.address,
>>>    						      pvmw.pmd, true);
>>> -				ret = false;
>>> -				page_vma_mapped_walk_done(&pvmw);
>>> -				break;
>>> +				flags &= ~TTU_SPLIT_HUGE_PMD;
>>> +				page_vma_mapped_walk_restart(&pvmw);
>>> +				continue;
>>>    			}
>>
>> The change looks more consistent to what we have in try_to_unmap().
>>
>> But the explanation above is not quite right I think. And consequently the comment above as well.
>>
>> PAE being set implies "single PMD" -> unshared.
> 
> The commit message might be improved with some additional context. The comment
> above pairs with the comment in __split_huge_pmd_locked()
> “In case we cannot clear PageAnonExclusive(), split the PMD
> only and let try_to_migrate_one() fail later”. What is problem with it?

With your explanation it's much clearer, thanks.

I'd remove some details from the comments about PAE like:

"split_huge_pmd_locked() might leave the folio mapped through PTEs. 
Retry the walk so we can detect this scenario and properly abort the walk."


With some clarifications along those lines

Acked-by: David Hildenbrand (arm) <david@kernel.org>

-- 
Cheers,

David


  reply	other threads:[~2026-02-04 20:43 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-02-04  0:42 [Patch v2] mm/huge_memory: fix early failure try_to_migrate() when split huge pmd for shared thp Wei Yang
2026-02-04  2:03 ` Baolin Wang
2026-02-04  2:22 ` Zi Yan
2026-02-04  3:12 ` Lance Yang
2026-02-04  9:41 ` Gavin Guo
2026-02-04 19:36 ` David Hildenbrand (arm)
2026-02-04 20:02   ` Zi Yan
2026-02-04 20:43     ` David Hildenbrand (arm) [this message]
2026-02-05  2:59       ` Wei Yang
2026-02-04 19:42 ` Andrew Morton
2026-02-05  3:04   ` Wei Yang
2026-02-05  3:13     ` Andrew Morton

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=df86ccfd-68a5-416e-81cc-02858e395b70@kernel.org \
    --to=david@kernel.org \
    --cc=Liam.Howlett@oracle.com \
    --cc=akpm@linux-foundation.org \
    --cc=baolin.wang@linux.alibaba.com \
    --cc=gavinguo@igalia.com \
    --cc=harry.yoo@oracle.com \
    --cc=jannh@google.com \
    --cc=lance.yang@linux.dev \
    --cc=linux-mm@kvack.org \
    --cc=lorenzo.stoakes@oracle.com \
    --cc=richard.weiyang@gmail.com \
    --cc=riel@surriel.com \
    --cc=stable@vger.kernel.org \
    --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 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.