From: Vernon Yang When the swap entries found exceed max_ptes_swap, the loop is left via break with folio still holding the xarray value that encodes the swap entry, not valid folio pointer. That value is passed to trace_mm_khugepaged_scan_file(), which feeds it to folio_pfn(). On FLATMEM and SPARSEMEM_VMEMMAP, the page_to_pfn() is plain pointer arithmetic, so the trace event merely prints bogus scan_pfn. On classic SPARSEMEM, the page_to_pfn() reads page->flags, dereferencing the tiny encoded integer and oopsing khugepaged whenever the trace event is enabled. So set folio to NULL before breaking out, the tracepoint maps NULL to scan_pfn of -1, just like exhausted scan naturally. Fixes: d41fd2016ed0 ("mm/khugepaged: add tracepoint to hpage_collapse_scan_file()") Cc: stable@vger.kernel.org Signed-off-by: Vernon Yang --- mm/khugepaged.c | 1 + 1 file changed, 1 insertion(+) diff --git a/mm/khugepaged.c b/mm/khugepaged.c index 617bca76db49..bc0d04c9162d 100644 --- a/mm/khugepaged.c +++ b/mm/khugepaged.c @@ -2696,6 +2696,7 @@ static enum scan_result collapse_scan_file(struct mm_struct *mm, if (xa_is_value(folio)) { swap += 1 << xas_get_order(&xas); if (swap > max_ptes_swap) { + folio = NULL; result = SCAN_EXCEED_SWAP_PTE; count_vm_event(THP_SCAN_EXCEED_SWAP_PTE); break; base-commit: 075b74841bd0065a3bda3440873c747938e69b68 -- 2.53.0