On Wed, Mar 20, 2024 at 03:40:42PM +0800, alexs@xxxxxxxxxx wrote: > -static int write_protect_page(struct vm_area_struct *vma, struct page *page, > +static int write_protect_page(struct vm_area_struct *vma, struct folio *folio, > pte_t *orig_pte) > { > struct mm_struct *mm = vma->vm_mm; > - DEFINE_PAGE_VMA_WALK(pvmw, page, vma, 0, 0); > + DEFINE_PAGE_VMA_WALK(pvmw, &folio->page, vma, 0, 0); We have a DEFINE_FOLIO_VMA_WALK > - pvmw.address = page_address_in_vma(page, vma); > + pvmw.address = page_address_in_vma(&folio->page, vma); We don't yet have a folio_address_in_vma(). This needs more study, so I approve of how you've converted this line. > - BUG_ON(PageTransCompound(page)); I might make this a VM_BUG_ON(folio_test_large(folio)) > @@ -1505,7 +1503,7 @@ static int try_to_merge_one_page(struct vm_area_struct *vma, > * ptes are necessarily already write-protected. But in either > * case, we need to lock and check page_count is not raised. > */ > - if (write_protect_page(vma, page, &orig_pte) == 0) { > + if (write_protect_page(vma, (struct folio *)page, &orig_pte) == 0) { I don't love this cast. I see why it's safe (called split_huge_page() above), but I'd rather see a call to page_folio() just to keep things tidy.