On Thu, Apr 08, 2021 at 04:43:21PM -0700, Axel Rasmussen wrote: [...] > @@ -1820,16 +1821,27 @@ static int shmem_getpage_gfp(struct inode *inode, pgoff_t index, > > page = pagecache_get_page(mapping, index, > FGP_ENTRY | FGP_HEAD | FGP_LOCK, 0); > - if (xa_is_value(page)) { > + swapped = xa_is_value(page); > + if (swapped) { > error = shmem_swapin_page(inode, index, &page, > sgp, gfp, vma, fault_type); > if (error == -EEXIST) > goto repeat; > - > *pagep = page; > - return error; > + if (error) > + return error; > } > > + if (page && vma && userfaultfd_minor(vma)) { > + unlock_page(page); > + put_page(page); > + *fault_type = handle_userfault(vmf, VM_UFFD_MINOR); > + return 0; > + } If we need to consider swapping for UFFDIO_CONTINUE later (as Hugh pointed out previously, which looks the right thing to do), it's indeed a bit awkward to swapin here. Maybe move this chunk to right after pagecache_get_page() returns? Then no need to touch the rest. > + > + if (swapped) > + return 0; > + > if (page) > hindex = page->index; > if (page && sgp == SGP_WRITE) > -- > 2.31.1.295.g9ea45b61b8-goog > -- Peter Xu