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 <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Reviewed-by: Jerome Glisse <[email protected]> Reviewed-by: Mike Rapoport <[email protected]> Cc: Andrea Arcangeli <[email protected]> Cc: Bobby Powers <[email protected]> Cc: Brian Geffon <[email protected]> Cc: David Hildenbrand <[email protected]> Cc: Denis Plotnikov <[email protected]> Cc: "Dr . David Alan Gilbert" <[email protected]> Cc: Hugh Dickins <[email protected]> Cc: Johannes Weiner <[email protected]> Cc: "Kirill A . Shutemov" <[email protected]> Cc: Martin Cracauer <[email protected]> Cc: Marty McFadden <[email protected]> Cc: Maya Gokhale <[email protected]> Cc: Mel Gorman <[email protected]> Cc: Mike Kravetz <[email protected]> Cc: Pavel Emelyanov <[email protected]> Cc: Rik van Riel <[email protected]> Cc: Shaohua Li <[email protected]> Link: http://lkml.kernel.org/r/[email protected] Signed-off-by: Linus Torvalds <[email protected]>
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)