linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
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?
> 


      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