From: "wuyifeng (C)" <wuyifeng10@huawei.com>
To: <linux-mm@kvack.org>, <akpm@linux-foundation.org>
Subject: [RFC] mm: Is flush_cache_page() in wp_page_reuse() really necessary?
Date: Mon, 29 Sep 2025 15:54:14 +0800 [thread overview]
Message-ID: <1ff65e11-bbdc-48b9-b703-c3038c8aa280@huawei.com> (raw)
In-Reply-To: <7a217590-1e37-4d80-9c5c-1f7d2c2b556c@huawei.com>
[Forwarded] This is the email I previously sent to the maintainer.
I forgot to copy the mailing list, so I am resending it here.
-------- 转发的消息 --------
主题: [RFC] mm: Is flush_cache_page() in wp_page_reuse() really necessary?
日期: Mon, 29 Sep 2025 15:29:37 +0800
From: wuyifeng (C) <wuyifeng10@huawei.com>
收件人: David Hildenbrand <david@redhat.com>, akpm@linux-foundation.org, lorenzo.stoakes@oracle.com
抄送: baohua@kernel.org
Hi Linux MM developers,
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);
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);
}
Since the mapping itself does not change, I am puzzled whether this
flush_cache_page() call is actually necessary.
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.
I have traced this back to the 2.6 kernel, and observed that the
`flush_cache_page` interface has already been present in the
reuse-related logic since then.
It appears that this part has not
received much attention over time, and the invocation of
`flush_cache_page` here may indeed be redundant?
code in do_wp_page (linux 2.6):
/* reuse the old page */
if (PageAnon(old_page) && !TestSetPageLocked(old_page)) {
int reuse = can_share_swap_page(old_page);
unlock_page(old_page);
if (reuse) {
flush_cache_page(vma, address, pfn);
entry = maybe_mkwrite(pte_mkyoung(pte_mkdirty(pte)),
vma);
ptep_set_access_flags(vma, address, page_table, entry, 1);
update_mmu_cache(vma, address, entry);
lazy_mmu_prot_update(entry);
pte_unmap(page_table);
spin_unlock(&mm->page_table_lock);
return VM_FAULT_MINOR|VM_FAULT_WRITE;
}
}
So my questions are:
Is the flush_cache_page() call in wp_page_reuse() actually
necessary?
If it is necessary, why is flush_cache_page() not required in the
reuse branch of do_huge_pmd_wp_page() for huge pages?
I would greatly appreciate your reply. Thank you very much!
Best regards,
[wuyifeng]
next parent reply other threads:[~2025-09-29 7:54 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) [this message]
[not found] ` <f775b4a3-77c4-46a8-92e2-17308097df3e@redhat.com>
2025-09-29 8:52 ` wuyifeng (C)
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=1ff65e11-bbdc-48b9-b703-c3038c8aa280@huawei.com \
--to=wuyifeng10@huawei.com \
--cc=akpm@linux-foundation.org \
--cc=linux-mm@kvack.org \
/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