mm: memory: use a folio in do_cow_fault()
authorKefeng Wang <wangkefeng.wang@huawei.com>
Sat, 18 Nov 2023 02:32:31 +0000 (10:32 +0800)
committerAndrew Morton <akpm@linux-foundation.org>
Tue, 12 Dec 2023 18:57:06 +0000 (10:57 -0800)
Use folio_prealloc() helper and convert to use a folio in do_cow_fault(),
which save five compound_head() calls.

Link: https://lkml.kernel.org/r/20231118023232.1409103-5-wangkefeng.wang@huawei.com
Signed-off-by: Kefeng Wang <wangkefeng.wang@huawei.com>
Reviewed-by: Vishal Moola (Oracle) <vishal.moola@gmail.com>
Cc: David Hildenbrand <david@redhat.com>
Cc: Matthew Wilcox (Oracle) <willy@infradead.org>
Cc: Sidhartha Kumar <sidhartha.kumar@oracle.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
mm/memory.c

index 32fb7e066197886e3ac3d43fb30d0a61cd5372d4..3d92b4a7b6e43bb56fc13ed7dbcc644a8ffad78f 100644 (file)
@@ -4656,6 +4656,7 @@ static vm_fault_t do_read_fault(struct vm_fault *vmf)
 static vm_fault_t do_cow_fault(struct vm_fault *vmf)
 {
        struct vm_area_struct *vma = vmf->vma;
+       struct folio *folio;
        vm_fault_t ret;
 
        ret = vmf_can_call_fault(vmf);
@@ -4664,16 +4665,11 @@ static vm_fault_t do_cow_fault(struct vm_fault *vmf)
        if (ret)
                return ret;
 
-       vmf->cow_page = alloc_page_vma(GFP_HIGHUSER_MOVABLE, vma, vmf->address);
-       if (!vmf->cow_page)
+       folio = folio_prealloc(vma->vm_mm, vma, vmf->address, false);
+       if (!folio)
                return VM_FAULT_OOM;
 
-       if (mem_cgroup_charge(page_folio(vmf->cow_page), vma->vm_mm,
-                               GFP_KERNEL)) {
-               put_page(vmf->cow_page);
-               return VM_FAULT_OOM;
-       }
-       folio_throttle_swaprate(page_folio(vmf->cow_page), GFP_KERNEL);
+       vmf->cow_page = &folio->page;
 
        ret = __do_fault(vmf);
        if (unlikely(ret & (VM_FAULT_ERROR | VM_FAULT_NOPAGE | VM_FAULT_RETRY)))
@@ -4682,7 +4678,7 @@ static vm_fault_t do_cow_fault(struct vm_fault *vmf)
                return ret;
 
        copy_user_highpage(vmf->cow_page, vmf->page, vmf->address, vma);
-       __SetPageUptodate(vmf->cow_page);
+       __folio_mark_uptodate(folio);
 
        ret |= finish_fault(vmf);
        unlock_page(vmf->page);
@@ -4691,7 +4687,7 @@ static vm_fault_t do_cow_fault(struct vm_fault *vmf)
                goto uncharge_out;
        return ret;
 uncharge_out:
-       put_page(vmf->cow_page);
+       folio_put(folio);
        return ret;
 }