mirror of
https://github.com/torvalds/linux.git
synced 2026-09-22 04:34:03 +02:00
mm: clarify the folio_free_swap() for do_swap_page()
Since commit 4b34f1d82c ("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().
Link: https://lore.kernel.org/20260701235955.36126-5-baohua@kernel.org
Signed-off-by: Barry Song (Xiaomi) <baohua@kernel.org>
Suggested-by: David Hildenbrand (Arm) <david@kernel.org>
Acked-by: David Hildenbrand (Arm) <david@kernel.org>
Cc: Baoquan He <baoquan.he@linux.dev>
Cc: Chris Li <chrisl@kernel.org>
Cc: Kairui Song <kasong@tencent.com>
Cc: Kemeng Shi <shikemeng@huaweicloud.com>
Cc: Liam R. Howlett <liam@infradead.org>
Cc: Lorenzo Stoakes <ljs@kernel.org>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Mike Rapoport <rppt@kernel.org>
Cc: Nhat Pham <nphamcs@gmail.com>
Cc: Shakeel Butt <shakeel.butt@linux.dev>
Cc: Suren Baghdasaryan <surenb@google.com>
Cc: Usama Arif <usama.arif@linux.dev>
Cc: Vlastimil Babka <vbabka@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
This commit is contained in:
parent
38f380f143
commit
3cedb745d3
20
mm/memory.c
20
mm/memory.c
|
|
@ -4509,7 +4509,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))
|
||||
|
|
@ -4525,14 +4525,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)
|
||||
|
|
@ -5036,10 +5034,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;
|
||||
}
|
||||
|
|
@ -5079,7 +5075,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);
|
||||
|
|
@ -5096,7 +5092,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;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user