From: "Barry Song (Xiaomi)" <baohua@kernel.org>
To: akpm@linux-foundation.org, linux-mm@kvack.org
Cc: baoquan.he@linux.dev, chrisl@kernel.org, david@kernel.org,
jp.kobryn@linux.dev, kasong@tencent.com, liam@infradead.org,
linux-kernel@vger.kernel.org, ljs@kernel.org, mhocko@suse.com,
nphamcs@gmail.com, rppt@kernel.org, shakeel.butt@linux.dev,
shikemeng@huaweicloud.com, surenb@google.com,
usama.arif@linux.dev, vbabka@kernel.org, youngjun.park@lge.com,
"Barry Song (Xiaomi)" <baohua@kernel.org>
Subject: [PATCH v3 4/4] mm: clarify the folio_free_swap() for do_swap_page()
Date: Thu, 2 Jul 2026 07:59:55 +0800 [thread overview]
Message-ID: <20260701235955.36126-5-baohua@kernel.org> (raw)
In-Reply-To: <20260701235955.36126-1-baohua@kernel.org>
Since commit 4b34f1d82c654 ("mm, swap: free the swap cache after
folio is mapped"), we have relied on do_wp_page() to handle the
non-exclusive case, where the folio may either be reused or require
CoW.
As a result, using the refcount in do_swap_page() to decide when to
free the swap cache is no longer necessary, since do_wp_page() can
handle this more cleanly and consistently.
We can now simply use FAULT_FLAG_WRITE together with exclusivity to
decide when to free the swap cache in do_swap_page().
Suggested-by: David Hildenbrand (Arm) <david@kernel.org>
Signed-off-by: Barry Song (Xiaomi) <baohua@kernel.org>
---
mm/memory.c | 20 ++++++++------------
1 file changed, 8 insertions(+), 12 deletions(-)
diff --git a/mm/memory.c b/mm/memory.c
index 4665405ace5a..a29cd38ad547 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -4516,7 +4516,7 @@ static vm_fault_t remove_device_exclusive_entry(struct vm_fault *vmf)
static inline bool should_try_to_free_swap(struct swap_info_struct *si,
struct folio *folio,
struct vm_area_struct *vma,
- unsigned int extra_refs,
+ bool exclusive,
unsigned int fault_flags)
{
if (!folio_test_swapcache(folio))
@@ -4532,14 +4532,12 @@ static inline bool should_try_to_free_swap(struct swap_info_struct *si,
if (mem_cgroup_swap_full(folio) || (vma->vm_flags & VM_LOCKED) ||
folio_test_mlocked(folio))
return true;
+
/*
- * If we want to map a page that's in the swapcache writable, we
- * have to detect via the refcount if we're really the exclusive
- * user. Try freeing the swapcache to get rid of the swapcache
- * reference only in case it's likely that we'll be the exclusive user.
+ * Free the swapcache only if we are the exclusive user and
+ * this is a write fault.
*/
- return (fault_flags & FAULT_FLAG_WRITE) && !folio_test_ksm(folio) &&
- folio_ref_count(folio) == (extra_refs + folio_nr_pages(folio));
+ return (fault_flags & FAULT_FLAG_WRITE) && exclusive;
}
static vm_fault_t pte_marker_clear(struct vm_fault *vmf)
@@ -5043,10 +5041,8 @@ vm_fault_t do_swap_page(struct vm_fault *vmf)
if ((vma->vm_flags & VM_WRITE) && !userfaultfd_pte_wp(vma, pte) &&
!pte_needs_soft_dirty_wp(vma, pte)) {
pte = pte_mkwrite(pte, vma);
- if (vmf->flags & FAULT_FLAG_WRITE) {
+ if (vmf->flags & FAULT_FLAG_WRITE)
pte = pte_mkdirty(pte);
- vmf->flags &= ~FAULT_FLAG_WRITE;
- }
}
rmap_flags |= RMAP_EXCLUSIVE;
}
@@ -5086,7 +5082,7 @@ vm_fault_t do_swap_page(struct vm_fault *vmf)
* Do it after mapping, so raced page faults will likely see the folio
* in swap cache and wait on the folio lock.
*/
- if (should_try_to_free_swap(si, folio, vma, nr_pages, vmf->flags))
+ if (should_try_to_free_swap(si, folio, vma, exclusive, vmf->flags))
folio_free_swap(folio);
folio_unlock(folio);
@@ -5103,7 +5099,7 @@ vm_fault_t do_swap_page(struct vm_fault *vmf)
folio_put(swapcache);
}
- if (vmf->flags & FAULT_FLAG_WRITE) {
+ if ((vmf->flags & FAULT_FLAG_WRITE) && !pte_write(pte)) {
ret |= do_wp_page(vmf);
if (ret & VM_FAULT_ERROR)
ret &= VM_FAULT_ERROR;
--
2.39.3 (Apple Git-146)
next prev parent reply other threads:[~2026-07-02 0:00 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-01 23:59 [PATCH v3 0/4] mm: drop redundant lru_add_drain in anon folio reuse paths Barry Song (Xiaomi)
2026-07-01 23:59 ` [PATCH v3 1/4] mm: avoid unnecessary lru drain for wp_can_reuse_anon_folio() Barry Song (Xiaomi)
2026-07-02 8:05 ` David Hildenbrand (Arm)
2026-07-06 8:18 ` Barry Song
2026-07-06 9:12 ` Baoquan He
2026-07-06 9:17 ` Barry Song
2026-07-01 23:59 ` [PATCH v3 2/4] mm: drop stale folio_ref_count()==1 check in do_swap_page reuse logic Barry Song (Xiaomi)
2026-07-02 8:07 ` David Hildenbrand (Arm)
2026-07-02 8:14 ` David Hildenbrand (Arm)
2026-07-06 8:14 ` Barry Song
2026-07-01 23:59 ` [PATCH v3 3/4] mm: entirely remove lru_add_drain in do_swap_page Barry Song (Xiaomi)
2026-07-01 23:59 ` Barry Song (Xiaomi) [this message]
2026-07-02 8:10 ` [PATCH v3 4/4] mm: clarify the folio_free_swap() for do_swap_page() David Hildenbrand (Arm)
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=20260701235955.36126-5-baohua@kernel.org \
--to=baohua@kernel.org \
--cc=akpm@linux-foundation.org \
--cc=baoquan.he@linux.dev \
--cc=chrisl@kernel.org \
--cc=david@kernel.org \
--cc=jp.kobryn@linux.dev \
--cc=kasong@tencent.com \
--cc=liam@infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=ljs@kernel.org \
--cc=mhocko@suse.com \
--cc=nphamcs@gmail.com \
--cc=rppt@kernel.org \
--cc=shakeel.butt@linux.dev \
--cc=shikemeng@huaweicloud.com \
--cc=surenb@google.com \
--cc=usama.arif@linux.dev \
--cc=vbabka@kernel.org \
--cc=youngjun.park@lge.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.