• Mina Almasry's avatar
    mm, hugetlb: fix simple resv_huge_pages underflow on UFFDIO_COPY · d84cf06e
    Mina Almasry authored
    The userfaultfd hugetlb tests cause a resv_huge_pages underflow.  This
    happens when hugetlb_mcopy_atomic_pte() is called with !is_continue on
    an index for which we already have a page in the cache.  When this
    happens, we allocate a second page, double consuming the reservation,
    and then fail to insert the page into the cache and return -EEXIST.
    
    To fix this, we first check if there is a page in the cache which
    already consumed the reservation, and return -EEXIST immediately if so.
    
    There is still a rare condition where we fail to copy the page contents
    AND race with a call for hugetlb_no_page() for this index and again we
    will underflow resv_huge_pages.  That is fixed in a more complicated
    patch not targeted for -stable.
    
    Test:
    
      Hacked the code locally such that resv_huge_pages underflows produce a
      warning, then:
    
      ./tools/testing/selftests/vm/userfaultfd hugetlb_shared 10
    	2 /tmp/kokonut_test/huge/userfaultfd_test && echo test success
      ./tools/testing/selftests/vm/userfaultfd hugetlb 10
    	2 /tmp/kokonut_test/huge/userfaultfd_test && echo test success
    
    Both tests succeed and produce no warnings.  After the test runs number
    of free/resv hugepages is correct.
    
    [mike.kravetz@oracle.com: changelog fixes]
    
    Link: https://lkml.kernel.org/r/20210528004649.85298-1-almasrymina@google.com
    Fixes: 8fb5debc
    
     ("userfaultfd: hugetlbfs: add hugetlb_mcopy_atomic_pte for userfaultfd support")
    Signed-off-by: default avatarMina Almasry <almasrymina@google.com>
    Reviewed-by: default avatarMike Kravetz <mike.kravetz@oracle.com>
    Cc: Axel Rasmussen <axelrasmussen@google.com>
    Cc: Peter Xu <peterx@redhat.com>
    Cc: <stable@vger.kernel.org>
    Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
    Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
    d84cf06e
hugetlb.c 165 KB