From: "wuyifeng (C)" <wuyifeng10@huawei.com>
To: David Hildenbrand <david@redhat.com>, <akpm@linux-foundation.org>,
<lorenzo.stoakes@oracle.com>
Cc: <baohua@kernel.org>, <linux-mm@kvack.org>
Subject: Re: [RFC] mm: Is flush_cache_page() in wp_page_reuse() really necessary?
Date: Mon, 29 Sep 2025 16:52:03 +0800 [thread overview]
Message-ID: <a0184970-f614-4e78-9952-f75737a45418@huawei.com> (raw)
In-Reply-To: <f775b4a3-77c4-46a8-92e2-17308097df3e@redhat.com>
Thanks for your reply and the pointers. I went through the kernel arch/ code
and looked into architectures that support PMD-level THP, such as arm64 and
x86_64 etc. I found that their flush_cache_page() implementations are all nop.
More precisely, for modern cache architectures (VIPT no-alias, PIPT),
flush_cache_page() is nop.
So the call in wp_page_reuse() looks more like a historical artifact, and it’s
hard to judge whether it was strictly necessary.
I really appreciate your clarifications!
Best regards,
Wuyifeng
在 2025/9/29 16:09, David Hildenbrand 写道:
> On 29.09.25 09:29, wuyifeng (C) wrote:
>> Hi Linux MM developers,
>
> Hi,
>
>>
>> I am reviewing the page fault handling code in the memory management
>> subsystem and came across a point that puzzled me regarding the use of
>> flush_cache_page().
>>
>> When I referred to Documentation/core-api/cachetlb.rst, it describes a
>> typical sequence in a page fault scenario:
>>
>> flush_cache_page(vma, addr, pfn);
>> set_pte(pte_pointer, new_pte_val);
>> flush_tlb_page(vma, addr);
>>
>
> The number of archs that actually implement flush_cache_page() is limited, so likely there is not a lot of interest around optimizing some out.
>
>>
>> That is, first the CPU cache is flushed, then the PTE is updated, and
>> finally the TLB is flushed for the corresponding virtual address. This
>> makes sense: when the virtual-to-physical mapping changes, flushing the
>> CPU cache is necessary to prevent stale or corrupted cache from affecting
>> the new mapping.
>>
>> However, in wp_page_reuse(), the virtual-to-physical mapping does
>> not change. The function looks like this:
>>
>> static inline void wp_page_reuse(struct vm_fault *vmf)
>> {
>> struct vm_area_struct *vma = vmf->vma;
>> struct page *page = vmf->page;
>> pte_t entry;
>>
>> if (page)
>> page_cpupid_xchg_last(page, (1 << LAST_CPUPID_SHIFT) - 1);
>>
>> flush_cache_page(vma, vmf->address, pte_pfn(vmf->orig_pte));
>> entry = pte_mkyoung(vmf->orig_pte);
>> entry = maybe_mkwrite(pte_mkdirty(entry), vma);
>> if (ptep_set_access_flags(vma, vmf->address, vmf->pte, entry, 1))
>> update_mmu_cache(vma, vmf->address, vmf->pte);
>> }
>
> Note that an "old" PTE might, depending on the arch, not actually have the hw-present bit set, so next access would trigger a page fault to maintain the clean/old PTE bit in software.
>
> So it could easily be that we are transitioning from non-hw-present to hw-present here.
>
> If that requires a flush_cache_page(), I really don't know :)
>
>>
>>
>> Since the mapping itself does not change, I am puzzled whether this
>> flush_cache_page() call is actually necessary.
>
> Same here. I have no idea if the scenario described above would require it, or only when we are changing something present to something non-present or differently-present.
>
>>
>> A similar situation appears in do_huge_pmd_wp_page(), which handles
>> huge pages. When the system reaches the reuse branch after the relevant
>> checks, the code looks like this:
>>
>> reuse:
>> entry = pmd_mkyoung(orig_pmd);
>> entry = maybe_pmd_mkwrite(pmd_mkdirty(entry), vma);
>> if (pmdp_set_access_flags(vma, haddr, vmf->pmd, entry, 1))
>> update_mmu_cache_pmd(vma, vmf->address, vmf->pmd);
>>
>>
>> Here, flush_cache_page() is not called. Instead, the code relies on
>> updating PMD access flags and calling update_mmu_cache_pmd() to refresh
>> the TLB.
>
> Does any architecture that cares about flush_cache_page() actually support PMD THPs?
>
> I mean, looking at mm/khugepaged.c, I cannot spot any flush_cache_*(). Maybe it's implicit, but my best guess is that no architecture that supports THPs really requires it?
>
prev parent reply other threads:[~2025-09-29 8:52 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <7a217590-1e37-4d80-9c5c-1f7d2c2b556c@huawei.com>
2025-09-29 7:54 ` wuyifeng (C)
[not found] ` <f775b4a3-77c4-46a8-92e2-17308097df3e@redhat.com>
2025-09-29 8:52 ` wuyifeng (C) [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=a0184970-f614-4e78-9952-f75737a45418@huawei.com \
--to=wuyifeng10@huawei.com \
--cc=akpm@linux-foundation.org \
--cc=baohua@kernel.org \
--cc=david@redhat.com \
--cc=linux-mm@kvack.org \
--cc=lorenzo.stoakes@oracle.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