Skip to content

Commit c1294d0

Browse files
aagittorvalds
authored andcommitted
userfaultfd: prevent khugepaged to merge if userfaultfd is armed
If userfaultfd is armed on a certain vma we can't "fill" the holes with zeroes or we'll break the userland on demand paging. The holes if the userfault is armed, are really missing information (not zeroes) that the userland has to load from network or elsewhere. The same issue happens for wrprotected ptes that we can't just convert into a single writable pmd_trans_huge. We could however in theory still merge across zeropages if only VM_UFFD_MISSING is set (so if VM_UFFD_WP is not set)... that could be slightly improved but it'd be much more complex code for a tiny corner case. Signed-off-by: Andrea Arcangeli <aarcange@redhat.com> Acked-by: Pavel Emelyanov <xemul@parallels.com> Cc: Sanidhya Kashyap <sanidhya.gatech@gmail.com> Cc: zhang.zhanghailiang@huawei.com Cc: "Kirill A. Shutemov" <kirill@shutemov.name> Cc: Andres Lagar-Cavilla <andreslc@google.com> Cc: Dave Hansen <dave.hansen@intel.com> Cc: Paolo Bonzini <pbonzini@redhat.com> Cc: Rik van Riel <riel@redhat.com> Cc: Mel Gorman <mgorman@suse.de> Cc: Andy Lutomirski <luto@amacapital.net> Cc: Hugh Dickins <hughd@google.com> Cc: Peter Feiner <pfeiner@google.com> Cc: "Dr. David Alan Gilbert" <dgilbert@redhat.com> Cc: Johannes Weiner <hannes@cmpxchg.org> Cc: "Huangpeng (Peter)" <peter.huangpeng@huawei.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
1 parent 19a809a commit c1294d0

File tree

1 file changed

+4
-2
lines changed

1 file changed

+4
-2
lines changed

mm/huge_memory.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2158,7 +2158,8 @@ static int __collapse_huge_page_isolate(struct vm_area_struct *vma,
21582158
_pte++, address += PAGE_SIZE) {
21592159
pte_t pteval = *_pte;
21602160
if (pte_none(pteval) || is_zero_pfn(pte_pfn(pteval))) {
2161-
if (++none_or_zero <= khugepaged_max_ptes_none)
2161+
if (!userfaultfd_armed(vma) &&
2162+
++none_or_zero <= khugepaged_max_ptes_none)
21622163
continue;
21632164
else
21642165
goto out;
@@ -2611,7 +2612,8 @@ static int khugepaged_scan_pmd(struct mm_struct *mm,
26112612
_pte++, _address += PAGE_SIZE) {
26122613
pte_t pteval = *_pte;
26132614
if (pte_none(pteval) || is_zero_pfn(pte_pfn(pteval))) {
2614-
if (++none_or_zero <= khugepaged_max_ptes_none)
2615+
if (!userfaultfd_armed(vma) &&
2616+
++none_or_zero <= khugepaged_max_ptes_none)
26152617
continue;
26162618
else
26172619
goto out_unmap;

0 commit comments

Comments
 (0)