Re: [PATCH] mm/khugepaged: Detecting uffd-wp vma more efficiently
From: Peter Xu <peterx@redhat.com>
Date: 2021-09-22 23:44:49
Also in:
lkml
On Wed, Sep 22, 2021 at 04:18:09PM -0700, Hugh Dickins wrote:
On Wed, 22 Sep 2021, Peter Xu wrote:quoted
Not installing pmd means uffd-minor can still trap any further faults just like before, afaiu. There's a very trivial detail that the pmd missing case will have a very slight code path change when the next page fault happens: in __handle_mm_fault() we'll first try to go into create_huge_pmd() once, however since shmem didn't provide huge_fault(), we'll go the VM_FAULT_FALLBACK path, and things will go like before when faulting on a small pte. The next UFFDIO_CONTINUE will allocate that missing pmd again, however it'll install a 4K page only.I think you're mistaken there. I can't tell you much about ->huge_fault(), something introduced for DAX I believe; but shmem has managed pmd mappings without it, since before ->huge_fault() was ever added.
Right, I wanted to express we didn't go into there, hence no way to allocate pmd there.
Look for the call to do_set_pmd() in finish_fault(): I think you'll find that is the way shmem's huge pmds get in. Earlier in the thread you suggested "shmem_getpage() only returns small pages": but it can very well return PageTransCompound pages, head or tail, which arrive at this do_set_pmd().
But note that uffd-minor will trap the shmem fault() even if pmd_none:
page = pagecache_get_page(mapping, index,
FGP_ENTRY | FGP_HEAD | FGP_LOCK, 0);
if (page && vma && userfaultfd_minor(vma)) {
if (!xa_is_value(page)) {
unlock_page(page);
put_page(page);
}
*fault_type = handle_userfault(vmf, VM_UFFD_MINOR);
return 0;
}
That's why I think it'll be fine, because it should only be UFFDIO_CONTINUE
that installs the pte (alongside with allocating the pmd).
Or did I miss something?
Thanks,
--
Peter Xu