Skip to content

Commit 28d41a4

Browse files
Matthew Wilcox (Oracle)akpm00
authored andcommitted
mm: convert wp_page_copy() to use folios
Use new_folio instead of new_page throughout, because we allocated it and know it's an order-0 folio. Most old_page uses become old_folio, but use vmf->page where we need the precise page. Link: https://lkml.kernel.org/r/[email protected] Signed-off-by: Matthew Wilcox (Oracle) <[email protected]> Reviewed-by: Zi Yan <[email protected]> Signed-off-by: Andrew Morton <[email protected]>
1 parent cb3184d commit 28d41a4

File tree

1 file changed

+32
-33
lines changed

1 file changed

+32
-33
lines changed

mm/memory.c

Lines changed: 32 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -3043,32 +3043,31 @@ static vm_fault_t wp_page_copy(struct vm_fault *vmf)
30433043
const bool unshare = vmf->flags & FAULT_FLAG_UNSHARE;
30443044
struct vm_area_struct *vma = vmf->vma;
30453045
struct mm_struct *mm = vma->vm_mm;
3046-
struct page *old_page = vmf->page;
3047-
struct page *new_page = NULL;
3046+
struct folio *old_folio = NULL;
3047+
struct folio *new_folio = NULL;
30483048
pte_t entry;
30493049
int page_copied = 0;
30503050
struct mmu_notifier_range range;
30513051
int ret;
30523052

30533053
delayacct_wpcopy_start();
30543054

3055+
if (vmf->page)
3056+
old_folio = page_folio(vmf->page);
30553057
if (unlikely(anon_vma_prepare(vma)))
30563058
goto oom;
30573059

30583060
if (is_zero_pfn(pte_pfn(vmf->orig_pte))) {
3059-
struct folio *new_folio;
3060-
30613061
new_folio = vma_alloc_zeroed_movable_folio(vma, vmf->address);
30623062
if (!new_folio)
30633063
goto oom;
3064-
new_page = &new_folio->page;
30653064
} else {
3066-
new_page = alloc_page_vma(GFP_HIGHUSER_MOVABLE, vma,
3067-
vmf->address);
3068-
if (!new_page)
3065+
new_folio = vma_alloc_folio(GFP_HIGHUSER_MOVABLE, 0, vma,
3066+
vmf->address, false);
3067+
if (!new_folio)
30693068
goto oom;
30703069

3071-
ret = __wp_page_copy_user(new_page, old_page, vmf);
3070+
ret = __wp_page_copy_user(&new_folio->page, vmf->page, vmf);
30723071
if (ret) {
30733072
/*
30743073
* COW failed, if the fault was solved by other,
@@ -3077,21 +3076,21 @@ static vm_fault_t wp_page_copy(struct vm_fault *vmf)
30773076
* from the second attempt.
30783077
* The -EHWPOISON case will not be retried.
30793078
*/
3080-
put_page(new_page);
3081-
if (old_page)
3082-
put_page(old_page);
3079+
folio_put(new_folio);
3080+
if (old_folio)
3081+
folio_put(old_folio);
30833082

30843083
delayacct_wpcopy_end();
30853084
return ret == -EHWPOISON ? VM_FAULT_HWPOISON : 0;
30863085
}
3087-
kmsan_copy_page_meta(new_page, old_page);
3086+
kmsan_copy_page_meta(&new_folio->page, vmf->page);
30883087
}
30893088

3090-
if (mem_cgroup_charge(page_folio(new_page), mm, GFP_KERNEL))
3089+
if (mem_cgroup_charge(new_folio, mm, GFP_KERNEL))
30913090
goto oom_free_new;
3092-
cgroup_throttle_swaprate(new_page, GFP_KERNEL);
3091+
cgroup_throttle_swaprate(&new_folio->page, GFP_KERNEL);
30933092

3094-
__SetPageUptodate(new_page);
3093+
__folio_mark_uptodate(new_folio);
30953094

30963095
mmu_notifier_range_init(&range, MMU_NOTIFY_CLEAR, 0, mm,
30973096
vmf->address & PAGE_MASK,
@@ -3103,16 +3102,16 @@ static vm_fault_t wp_page_copy(struct vm_fault *vmf)
31033102
*/
31043103
vmf->pte = pte_offset_map_lock(mm, vmf->pmd, vmf->address, &vmf->ptl);
31053104
if (likely(pte_same(*vmf->pte, vmf->orig_pte))) {
3106-
if (old_page) {
3107-
if (!PageAnon(old_page)) {
3108-
dec_mm_counter(mm, mm_counter_file(old_page));
3105+
if (old_folio) {
3106+
if (!folio_test_anon(old_folio)) {
3107+
dec_mm_counter(mm, mm_counter_file(&old_folio->page));
31093108
inc_mm_counter(mm, MM_ANONPAGES);
31103109
}
31113110
} else {
31123111
inc_mm_counter(mm, MM_ANONPAGES);
31133112
}
31143113
flush_cache_page(vma, vmf->address, pte_pfn(vmf->orig_pte));
3115-
entry = mk_pte(new_page, vma->vm_page_prot);
3114+
entry = mk_pte(&new_folio->page, vma->vm_page_prot);
31163115
entry = pte_sw_mkyoung(entry);
31173116
if (unlikely(unshare)) {
31183117
if (pte_soft_dirty(vmf->orig_pte))
@@ -3131,8 +3130,8 @@ static vm_fault_t wp_page_copy(struct vm_fault *vmf)
31313130
* some TLBs while the old PTE remains in others.
31323131
*/
31333132
ptep_clear_flush_notify(vma, vmf->address, vmf->pte);
3134-
page_add_new_anon_rmap(new_page, vma, vmf->address);
3135-
lru_cache_add_inactive_or_unevictable(new_page, vma);
3133+
folio_add_new_anon_rmap(new_folio, vma, vmf->address);
3134+
folio_add_lru_vma(new_folio, vma);
31363135
/*
31373136
* We call the notify macro here because, when using secondary
31383137
* mmu page tables (such as kvm shadow page tables), we want the
@@ -3141,7 +3140,7 @@ static vm_fault_t wp_page_copy(struct vm_fault *vmf)
31413140
BUG_ON(unshare && pte_write(entry));
31423141
set_pte_at_notify(mm, vmf->address, vmf->pte, entry);
31433142
update_mmu_cache(vma, vmf->address, vmf->pte);
3144-
if (old_page) {
3143+
if (old_folio) {
31453144
/*
31463145
* Only after switching the pte to the new page may
31473146
* we remove the mapcount here. Otherwise another
@@ -3164,38 +3163,38 @@ static vm_fault_t wp_page_copy(struct vm_fault *vmf)
31643163
* mapcount is visible. So transitively, TLBs to
31653164
* old page will be flushed before it can be reused.
31663165
*/
3167-
page_remove_rmap(old_page, vma, false);
3166+
page_remove_rmap(vmf->page, vma, false);
31683167
}
31693168

31703169
/* Free the old page.. */
3171-
new_page = old_page;
3170+
new_folio = old_folio;
31723171
page_copied = 1;
31733172
} else {
31743173
update_mmu_tlb(vma, vmf->address, vmf->pte);
31753174
}
31763175

3177-
if (new_page)
3178-
put_page(new_page);
3176+
if (new_folio)
3177+
folio_put(new_folio);
31793178

31803179
pte_unmap_unlock(vmf->pte, vmf->ptl);
31813180
/*
31823181
* No need to double call mmu_notifier->invalidate_range() callback as
31833182
* the above ptep_clear_flush_notify() did already call it.
31843183
*/
31853184
mmu_notifier_invalidate_range_only_end(&range);
3186-
if (old_page) {
3185+
if (old_folio) {
31873186
if (page_copied)
3188-
free_swap_cache(old_page);
3189-
put_page(old_page);
3187+
free_swap_cache(&old_folio->page);
3188+
folio_put(old_folio);
31903189
}
31913190

31923191
delayacct_wpcopy_end();
31933192
return 0;
31943193
oom_free_new:
3195-
put_page(new_page);
3194+
folio_put(new_folio);
31963195
oom:
3197-
if (old_page)
3198-
put_page(old_page);
3196+
if (old_folio)
3197+
folio_put(old_folio);
31993198

32003199
delayacct_wpcopy_end();
32013200
return VM_FAULT_OOM;

0 commit comments

Comments
 (0)