summaryrefslogtreecommitdiff
path: root/mm/hugetlb.c
diff options
context:
space:
mode:
authorJiri Kosina <jkosina@suse.cz>2019-09-22 22:29:00 +0200
committerJiri Kosina <jkosina@suse.cz>2019-09-22 22:29:00 +0200
commit53c716412708db7000e06292fb89b2609f9a48f7 (patch)
tree3ede481ee0926f0e53e14bba61028d307d58296c /mm/hugetlb.c
parente6d64ce06c28b615ebfeab7b8bfad6136ea83095 (diff)
parentaec256d0ecd561036f188dbc8fa7924c47a9edfd (diff)
Merge branch 'for-5.4/apple' into for-linus
- stuck 'fn' key fix for hid-apple from Joao Moreno Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Diffstat (limited to 'mm/hugetlb.c')
-rw-r--r--mm/hugetlb.c19
1 files changed, 19 insertions, 0 deletions
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index ede7e7f5d1ab..6d7296dd11b8 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -3856,6 +3856,25 @@ retry:
page = alloc_huge_page(vma, haddr, 0);
if (IS_ERR(page)) {
+ /*
+ * Returning error will result in faulting task being
+ * sent SIGBUS. The hugetlb fault mutex prevents two
+ * tasks from racing to fault in the same page which
+ * could result in false unable to allocate errors.
+ * Page migration does not take the fault mutex, but
+ * does a clear then write of pte's under page table
+ * lock. Page fault code could race with migration,
+ * notice the clear pte and try to allocate a page
+ * here. Before returning error, get ptl and make
+ * sure there really is no pte entry.
+ */
+ ptl = huge_pte_lock(h, mm, ptep);
+ if (!huge_pte_none(huge_ptep_get(ptep))) {
+ ret = 0;
+ spin_unlock(ptl);
+ goto out;
+ }
+ spin_unlock(ptl);
ret = vmf_error(PTR_ERR(page));
goto out;
}