On 3/18/21 4:08 AM, Dan Williams wrote: > Now that device-dax and filesystem-dax are guaranteed to unmap all user > mappings of devmap / DAX pages before tearing down the 'struct page' > array, get_user_pages_fast() can rely on its traditional synchronization > method "validate_pte(); get_page(); revalidate_pte()" to catch races with > device shutdown. Specifically the unmap guarantee ensures that gup-fast > either succeeds in taking a page reference (lock-less), or it detects a > need to fall back to the slow path where the device presence can be > revalidated with locks held. [...] > @@ -2087,21 +2078,26 @@ static int gup_pte_range(pmd_t pmd, unsigned long addr, unsigned long end, > #endif /* CONFIG_ARCH_HAS_PTE_SPECIAL */ > > #if defined(CONFIG_ARCH_HAS_PTE_DEVMAP) && defined(CONFIG_TRANSPARENT_HUGEPAGE) > + > static int __gup_device_huge(unsigned long pfn, unsigned long addr, > unsigned long end, unsigned int flags, > struct page **pages, int *nr) > { > int nr_start = *nr; > - struct dev_pagemap *pgmap = NULL; > > do { > - struct page *page = pfn_to_page(pfn); > + struct page *page; > + > + /* > + * Typically pfn_to_page() on a devmap pfn is not safe > + * without holding a live reference on the hosting > + * pgmap. In the gup-fast path it is safe because any > + * races will be resolved by either gup-fast taking a > + * reference or the shutdown path unmapping the pte to > + * trigger gup-fast to fall back to the slow path. > + */ > + page = pfn_to_page(pfn); > > - pgmap = get_dev_pagemap(pfn, pgmap); > - if (unlikely(!pgmap)) { > - undo_dev_pagemap(nr, nr_start, flags, pages); > - return 0; > - } > SetPageReferenced(page); > pages[*nr] = page; > if (unlikely(!try_grab_page(page, flags))) { So for allowing FOLL_LONGTERM[0] would it be OK if we used page->pgmap after try_grab_page() for checking pgmap type to see if we are in a device-dax longterm pin? Joao [0] https://lore.kernel.org/linux-mm/6a18179e-65f7-367d-89a9-d5162f10fef0@xxxxxxxxxx/