From: Huang Ying <[email protected]> If THP migration is enabled, the following situation is possible,
- A THP is mapped at source address - Migration is started to move the THP to another node - Page fault occurs - The PMD (migration entry) is copied to the destination address in mremap That is, it is possible for handle_userfault() encounter a PMD entry which has been handled but !pmd_present(). In the current implementation, we will wait for such PMD entries, which may cause unnecessary waiting, and potential soft lockup. This is fixed via avoiding to wait when !pmd_present(), only wait when pmd_none(). Question: I found userfaultfd_must_wait() is always called when PMD or PTE is none, and with mm->mmap_sem read-lock held. mremap() will write-lock mm->mmap_sem. And UFFDIO_COPY don't support to copy THP mapping. So the situation described above couldn't happen in practice? Signed-off-by: "Huang, Ying" <[email protected]> Cc: Andrea Arcangeli <[email protected]> Cc: Mike Kravetz <[email protected]> Cc: Mike Rapoport <[email protected]> Cc: "Kirill A. Shutemov" <[email protected]> Cc: Alexander Viro <[email protected]> Cc: Zi Yan <[email protected]> Cc: Naoya Horiguchi <[email protected]> --- fs/userfaultfd.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/fs/userfaultfd.c b/fs/userfaultfd.c index b5a0193e1960..0fcf66c3e439 100644 --- a/fs/userfaultfd.c +++ b/fs/userfaultfd.c @@ -294,10 +294,13 @@ static inline bool userfaultfd_must_wait(struct userfaultfd_ctx *ctx, * pmd_trans_unstable) of the pmd. */ _pmd = READ_ONCE(*pmd); - if (!pmd_present(_pmd)) + if (pmd_none(_pmd)) goto out; ret = false; + if (!pmd_present(_pmd)) + goto out; + if (pmd_trans_huge(_pmd)) goto out; -- 2.14.2

