On Tue, Jan 14, 2025 at 09:22:00AM -0800, Dan Williams wrote: > 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. Yes, thanks Dave and Dan and apologies for missing that originally. Looking at the thread I suspect I went down the rabbit hole of trying to implement vmf_insert_folio() and when that wasn't possible forgot to come back and fix this up. I have added a return code to insert_pfn_pmd() to indicate whether or not the pgtable was consumed. I have also added a comment in the commit log explaining why a vmf_insert_folio() isn't useful. - Alistair