]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 4.19
authorSasha Levin <sashal@kernel.org>
Tue, 8 Jun 2021 14:27:15 +0000 (10:27 -0400)
committerSasha Levin <sashal@kernel.org>
Tue, 8 Jun 2021 14:27:15 +0000 (10:27 -0400)
Signed-off-by: Sasha Levin <sashal@kernel.org>
queue-4.19/mm-hugetlb-fix-simple-resv_huge_pages-underflow-on-u.patch [new file with mode: 0644]
queue-4.19/series

diff --git a/queue-4.19/mm-hugetlb-fix-simple-resv_huge_pages-underflow-on-u.patch b/queue-4.19/mm-hugetlb-fix-simple-resv_huge_pages-underflow-on-u.patch
new file mode 100644 (file)
index 0000000..8399c94
--- /dev/null
@@ -0,0 +1,82 @@
+From a4d7d806f90e3b6216041cac551eb6363f0d6681 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 4 Jun 2021 20:01:36 -0700
+Subject: mm, hugetlb: fix simple resv_huge_pages underflow on UFFDIO_COPY
+
+From: Mina Almasry <almasrymina@google.com>
+
+[ Upstream commit d84cf06e3dd8c5c5b547b5d8931015fc536678e5 ]
+
+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: 8fb5debc5fcd ("userfaultfd: hugetlbfs: add hugetlb_mcopy_atomic_pte for userfaultfd support")
+Signed-off-by: Mina Almasry <almasrymina@google.com>
+Reviewed-by: Mike 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: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ mm/hugetlb.c | 14 ++++++++++++--
+ 1 file changed, 12 insertions(+), 2 deletions(-)
+
+diff --git a/mm/hugetlb.c b/mm/hugetlb.c
+index 2f769a661568..c69f12e4c149 100644
+--- a/mm/hugetlb.c
++++ b/mm/hugetlb.c
+@@ -4154,10 +4154,20 @@ int hugetlb_mcopy_atomic_pte(struct mm_struct *dst_mm,
+       struct page *page;
+       if (!*pagep) {
+-              ret = -ENOMEM;
++              /* If a page already exists, then it's UFFDIO_COPY for
++               * a non-missing case. Return -EEXIST.
++               */
++              if (vm_shared &&
++                  hugetlbfs_pagecache_present(h, dst_vma, dst_addr)) {
++                      ret = -EEXIST;
++                      goto out;
++              }
++
+               page = alloc_huge_page(dst_vma, dst_addr, 0);
+-              if (IS_ERR(page))
++              if (IS_ERR(page)) {
++                      ret = -ENOMEM;
+                       goto out;
++              }
+               ret = copy_huge_page_from_user(page,
+                                               (const void __user *) src_addr,
+-- 
+2.30.2
+
index f8b4ffc2ad2c0002b1ec246d545435bb4d40fe80..badbb49395889b8ac183693b56a1d341f78a8ac9 100644 (file)
@@ -36,3 +36,4 @@ btrfs-mark-ordered-extent-and-inode-with-error-if-we-fail-to-finish.patch
 btrfs-fix-error-handling-in-btrfs_del_csums.patch
 btrfs-return-errors-from-btrfs_del_csums-in-cleanup_ref_head.patch
 btrfs-fixup-error-handling-in-fixup_inode_link_counts.patch
+mm-hugetlb-fix-simple-resv_huge_pages-underflow-on-u.patch