David Hildenbrand wrote: > > +vm_fault_t vmf_insert_folio_pmd(struct vm_fault *vmf, struct folio *folio, bool write) > > +{ > > + struct vm_area_struct *vma = vmf->vma; > > + unsigned long addr = vmf->address & PMD_MASK; > > + struct mm_struct *mm = vma->vm_mm; > > + spinlock_t *ptl; > > + pgtable_t pgtable = NULL; > > + > > + if (addr < vma->vm_start || addr >= vma->vm_end) > > + return VM_FAULT_SIGBUS; > > + > > + if (WARN_ON_ONCE(folio_order(folio) != PMD_ORDER)) > > + return VM_FAULT_SIGBUS; > > + > > + if (arch_needs_pgtable_deposit()) { > > + pgtable = pte_alloc_one(vma->vm_mm); > > + if (!pgtable) > > + return VM_FAULT_OOM; > > + } > > This is interesting and nasty at the same time (only to make ppc64 boo3s > with has tables happy). But it seems to be the right thing to do. > > > + > > + ptl = pmd_lock(mm, vmf->pmd); > > + if (pmd_none(*vmf->pmd)) { > > + folio_get(folio); > > + folio_add_file_rmap_pmd(folio, &folio->page, vma); > > + add_mm_counter(mm, mm_counter_file(folio), HPAGE_PMD_NR); > > + } > > + insert_pfn_pmd(vma, addr, vmf->pmd, pfn_to_pfn_t(folio_pfn(folio)), > > + vma->vm_page_prot, write, pgtable); > > + spin_unlock(ptl); > > + if (pgtable) > > + pte_free(mm, pgtable); > > Ehm, are you unconditionally freeing the pgtable, even if consumed by > insert_pfn_pmd() ? > > Note that setting pgtable to NULL in insert_pfn_pmd() when consumed will > not be visible here. > > You'd have to pass a pointer to the ... pointer (&pgtable). > > ... unless I am missing something, staring at the diff. In fact I glazed over the fact that this has been commented on before and assumed it was fixed: http://lore.kernel.org/66f61ce4da80_964f2294fb@xxxxxxxxxxxxxxxxxxxxxxxxx.notmuch So, yes, insert_pfn_pmd needs to take &pgtable to report back if the allocation got consumed. Good catch.