From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7ACDF39EF27 for ; Thu, 2 Jul 2026 00:00:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1782950419; cv=none; b=ggomssyzjHusMb9ctgwlZ6An4W/6IEEXd0I9afXx9y2Dn9uNf5wzJYX91hjcs6afS4v2lG2ukeucNfn3Gp4UkxCzBjqKpteZWqWdlAlL1x7CJSEeV0yEdoI/XYxdYsR2y7IwrebQtVI3c0dfeLbnA4rDvOqzpnnm6JbX+wj0o0g= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1782950419; c=relaxed/simple; bh=+qvMvl8mVwwO4onhzcOs0wRkuoR8h331P3L348dV9dY=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=WQgWsQwruF/bhOrKtCHKuPQ3TGsQwL1A+vJfMClt+fy2eaJESdt7NzVu3TZI7qmARrb3gpIAJ6mWVngabXHWPaFUVTxWhoqC/P0qeZNHOSlvn+LuLvrRhpghLinAIgj08aJpysw4dSg5MQoXkd64TcibLbkzMev5oKejSwA5F9w= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=hDjSXhFX; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="hDjSXhFX" Received: by smtp.kernel.org (Postfix) with ESMTPSA id C13B11F00A3E; Thu, 2 Jul 2026 00:00:14 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1782950418; bh=piv2DrumZ4k3choYGidxInIFhCfd9obWqsD0L5fugWY=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=hDjSXhFX4imlqsGLFRZyZH6odgZkllGkzFHF3nNngXx6+KS/DCNZNKQSrkFK+0fNc s6oBdl7ExcF/JRdAobWDK0Hnza3lf9gn1djBxm4eQ3/+nck61UcwUqriG1BxB7gxST He/GDD+BiJMtN4xe6oGt0cZBno7LNC8Dzm5YZT/nt509Qx0K6CbsSsM93TfhiJfK51 3q9oEhHJ0Knud2zA9q8hYOEMNHgERQCK3xpxMc+61o2Z2SLR/n2iPp0tOzGMJrXGbR vVJ0igKU4I/nTLqNaG7EpeWqXU+0vB0ukp68ajaQogcKPvL9FjTkxL9z3BfzjB54qJ UOhVo7UWjAETw== From: "Barry Song (Xiaomi)" 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)" Subject: [PATCH v3 4/4] mm: clarify the folio_free_swap() for do_swap_page() Date: Thu, 2 Jul 2026 07:59:55 +0800 Message-Id: <20260701235955.36126-5-baohua@kernel.org> X-Mailer: git-send-email 2.39.3 (Apple Git-146) In-Reply-To: <20260701235955.36126-1-baohua@kernel.org> References: <20260701235955.36126-1-baohua@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit 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) Signed-off-by: Barry Song (Xiaomi) --- 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)