On Tue, Feb 18, 2025 at 05:20:28PM +0100, Alexander Gordeev wrote: > > +++ b/arch/s390/include/asm/pgtable.h > > @@ -1451,12 +1451,7 @@ static inline pte_t mk_pte_phys(unsigned long physpage, pgprot_t pgprot) > > > > static inline pte_t mk_pte(struct page *page, pgprot_t pgprot) > > { > > - unsigned long physpage = page_to_phys(page); > > - pte_t __pte = mk_pte_phys(physpage, pgprot); > > - > > - if (pte_write(__pte) && PageDirty(page)) > > - __pte = pte_mkdirty(__pte); > > - return __pte; > > + return mk_pte_phys(page_to_phys(page), pgprot); > > } > > With the above the implicit dirtifying of hugetlb PTEs (as result of > mk_huge_pte() -> mk_pte()) in make_huge_pte() is removed: > > static pte_t make_huge_pte(struct vm_area_struct *vma, struct page *page, > bool try_mkwrite) > { > ... > if (try_mkwrite && (vma->vm_flags & VM_WRITE)) { > entry = huge_pte_mkwrite(huge_pte_mkdirty(mk_huge_pte(page, > vma->vm_page_prot))); > } else { > entry = huge_pte_wrprotect(mk_huge_pte(page, > vma->vm_page_prot)); > } Took me a moment to spot how this was getting invoked; for anyone else playing along, it's mk_huge_pte() which calls mk_pte(). But I'm not sure how you lose out on the PTE being marked dirty. In the first arm that you've quoted, the pte is made dirty anyway. In the second arm, it's being writeprotected, so marking it dirty isn't a helpful thing to do because writing to it will cause a fault anyway? I know s390 is a little different, so there's probably something I'm missing.