[-next,3/7] mm: memory: convert do_cow_fault to use folios

Message ID 20230112083006.163393-4-wangkefeng.wang@huawei.com
State New
Headers
Series mm: remove cgroup_throttle_swaprate() completely |

Commit Message

Kefeng Wang Jan. 12, 2023, 8:30 a.m. UTC
  The page functions are converted to corresponding folio functions in
do_cow_fault().

Signed-off-by: Kefeng Wang <wangkefeng.wang@huawei.com>
---
 mm/memory.c | 23 +++++++++++++----------
 1 file changed, 13 insertions(+), 10 deletions(-)
  

Comments

Matthew Wilcox Jan. 13, 2023, 3:37 p.m. UTC | #1
On Thu, Jan 12, 2023 at 04:30:02PM +0800, Kefeng Wang wrote:
> -	vmf->cow_page = alloc_page_vma(GFP_HIGHUSER_MOVABLE, vma, vmf->address);
> -	if (!vmf->cow_page)
> +	cow_folio = vma_alloc_folio(GFP_HIGHUSER_MOVABLE, 0, vma, vmf->address,
> +				    false);
> +	if (!cow_folio)

I have a patch I've been sitting on that converts vmf->cow_page to be
a folio.  I think this series is well and truly wrecked at this point,
so let me go back and dig it out; see if it still makes sense.

I'm a bit unsure about it because maybe we want to allocate
high(ish)-order folios on COW fault, and if we do, then maybe we want
to align them in some way with the virtual addresses, or the other
folios in the VMA.  And then we might want to indicate the precise
page for this page fault rather than have this page fault be the
start of a multi-order folio.
  
Kefeng Wang Jan. 16, 2023, 11:31 a.m. UTC | #2
On 2023/1/13 23:37, Matthew Wilcox wrote:
> On Thu, Jan 12, 2023 at 04:30:02PM +0800, Kefeng Wang wrote:
>> -	vmf->cow_page = alloc_page_vma(GFP_HIGHUSER_MOVABLE, vma, vmf->address);
>> -	if (!vmf->cow_page)
>> +	cow_folio = vma_alloc_folio(GFP_HIGHUSER_MOVABLE, 0, vma, vmf->address,
>> +				    false);
>> +	if (!cow_folio)
> 
> I have a patch I've been sitting on that converts vmf->cow_page to be
> a folio.  I think this series is well and truly wrecked at this point,
> so let me go back and dig it out; see if it still makes sense.
> 

For now, as vmf->page and vmf->cow_page used in do_cow_page(), it only 
supports cow on a page, and after converting, the folio still is 0 order,

> I'm a bit unsure about it because maybe we want to allocate
> high(ish)-order folios on COW fault, and if we do, then maybe we want
> to align them in some way with the virtual addresses, or the other
> folios in the VMA.  And then we might want to indicate the precise
> page for this page fault rather than have this page fault be the
> start of a multi-order folio.
> 
This means that if high(ish)-order folios/multi-order folio on cow, it
needs additional jobs and precise page for this pagefault, but for 
order-0, the converting is right but could break/mislead future logical? 
not very clear about this part, but let's wait for your patches.
  

Patch

diff --git a/mm/memory.c b/mm/memory.c
index 1cfdb0fd8d79..f29bca499e0d 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -4507,22 +4507,24 @@  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 *cow_folio, *folio;
 	vm_fault_t ret;
 
 	if (unlikely(anon_vma_prepare(vma)))
 		return VM_FAULT_OOM;
 
-	vmf->cow_page = alloc_page_vma(GFP_HIGHUSER_MOVABLE, vma, vmf->address);
-	if (!vmf->cow_page)
+	cow_folio = vma_alloc_folio(GFP_HIGHUSER_MOVABLE, 0, vma, vmf->address,
+				    false);
+	if (!cow_folio)
 		return VM_FAULT_OOM;
 
-	if (mem_cgroup_charge(page_folio(vmf->cow_page), vma->vm_mm,
-				GFP_KERNEL)) {
-		put_page(vmf->cow_page);
+	if (mem_cgroup_charge(cow_folio, vma->vm_mm, GFP_KERNEL)) {
+		folio_put(cow_folio);
 		return VM_FAULT_OOM;
 	}
-	cgroup_throttle_swaprate(vmf->cow_page, GFP_KERNEL);
+	folio_throttle_swaprate(cow_folio, GFP_KERNEL);
 
+	vmf->cow_page = &cow_folio->page;
 	ret = __do_fault(vmf);
 	if (unlikely(ret & (VM_FAULT_ERROR | VM_FAULT_NOPAGE | VM_FAULT_RETRY)))
 		goto uncharge_out;
@@ -4530,16 +4532,17 @@  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(cow_folio);
 
 	ret |= finish_fault(vmf);
-	unlock_page(vmf->page);
-	put_page(vmf->page);
+	folio = page_folio(vmf->page);
+	folio_unlock(folio);
+	folio_put(folio);
 	if (unlikely(ret & (VM_FAULT_ERROR | VM_FAULT_NOPAGE | VM_FAULT_RETRY)))
 		goto uncharge_out;
 	return ret;
 uncharge_out:
-	put_page(vmf->cow_page);
+	folio_put(cow_folio);
 	return ret;
 }