Skip to content

Commit e1e267c

Browse files
xzpetertorvalds
authored andcommitted
khugepaged: skip collapse if uffd-wp detected
Don't collapse the huge PMD if there is any userfault write protected small PTEs. The problem is that the write protection is in small page granularity and there's no way to keep all these write protection information if the small pages are going to be merged into a huge PMD. The same thing needs to be considered for swap entries and migration entries. So do the check as well disregarding khugepaged_max_ptes_swap. Signed-off-by: Peter Xu <peterx@redhat.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Reviewed-by: Jerome Glisse <jglisse@redhat.com> Reviewed-by: Mike Rapoport <rppt@linux.vnet.ibm.com> Cc: Andrea Arcangeli <aarcange@redhat.com> Cc: Bobby Powers <bobbypowers@gmail.com> Cc: Brian Geffon <bgeffon@google.com> Cc: David Hildenbrand <david@redhat.com> Cc: Denis Plotnikov <dplotnikov@virtuozzo.com> Cc: "Dr . David Alan Gilbert" <dgilbert@redhat.com> Cc: Hugh Dickins <hughd@google.com> Cc: Johannes Weiner <hannes@cmpxchg.org> Cc: "Kirill A . Shutemov" <kirill@shutemov.name> Cc: Martin Cracauer <cracauer@cons.org> Cc: Marty McFadden <mcfadden8@llnl.gov> Cc: Maya Gokhale <gokhale2@llnl.gov> Cc: Mel Gorman <mgorman@suse.de> Cc: Mike Kravetz <mike.kravetz@oracle.com> Cc: Pavel Emelyanov <xemul@openvz.org> Cc: Rik van Riel <riel@redhat.com> Cc: Shaohua Li <shli@fb.com> Link: http://lkml.kernel.org/r/20200220163112.11409-12-peterx@redhat.com Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
1 parent f45ec5f commit e1e267c

File tree

2 files changed

+24
-0
lines changed

2 files changed

+24
-0
lines changed

include/trace/events/huge_memory.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
EM( SCAN_PMD_NULL, "pmd_null") \
1414
EM( SCAN_EXCEED_NONE_PTE, "exceed_none_pte") \
1515
EM( SCAN_PTE_NON_PRESENT, "pte_non_present") \
16+
EM( SCAN_PTE_UFFD_WP, "pte_uffd_wp") \
1617
EM( SCAN_PAGE_RO, "no_writable_page") \
1718
EM( SCAN_LACK_REFERENCED_PAGE, "lack_referenced_page") \
1819
EM( SCAN_PAGE_NULL, "page_null") \

mm/khugepaged.c

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ enum scan_result {
2929
SCAN_PMD_NULL,
3030
SCAN_EXCEED_NONE_PTE,
3131
SCAN_PTE_NON_PRESENT,
32+
SCAN_PTE_UFFD_WP,
3233
SCAN_PAGE_RO,
3334
SCAN_LACK_REFERENCED_PAGE,
3435
SCAN_PAGE_NULL,
@@ -1137,6 +1138,15 @@ static int khugepaged_scan_pmd(struct mm_struct *mm,
11371138
pte_t pteval = *_pte;
11381139
if (is_swap_pte(pteval)) {
11391140
if (++unmapped <= khugepaged_max_ptes_swap) {
1141+
/*
1142+
* Always be strict with uffd-wp
1143+
* enabled swap entries. Please see
1144+
* comment below for pte_uffd_wp().
1145+
*/
1146+
if (pte_swp_uffd_wp(pteval)) {
1147+
result = SCAN_PTE_UFFD_WP;
1148+
goto out_unmap;
1149+
}
11401150
continue;
11411151
} else {
11421152
result = SCAN_EXCEED_SWAP_PTE;
@@ -1156,6 +1166,19 @@ static int khugepaged_scan_pmd(struct mm_struct *mm,
11561166
result = SCAN_PTE_NON_PRESENT;
11571167
goto out_unmap;
11581168
}
1169+
if (pte_uffd_wp(pteval)) {
1170+
/*
1171+
* Don't collapse the page if any of the small
1172+
* PTEs are armed with uffd write protection.
1173+
* Here we can also mark the new huge pmd as
1174+
* write protected if any of the small ones is
1175+
* marked but that could bring uknown
1176+
* userfault messages that falls outside of
1177+
* the registered range. So, just be simple.
1178+
*/
1179+
result = SCAN_PTE_UFFD_WP;
1180+
goto out_unmap;
1181+
}
11591182
if (pte_write(pteval))
11601183
writable = true;
11611184

0 commit comments

Comments
 (0)