MADV_COLLAPSE acts on one hugepage-aligned/sized region at a time, until it has collapsed all eligible memory contained within the bounds supplied by the user. At the top of each hugepage iteration we (re)lock mmap_lock and (re)validate the VMA for eligibility and update variables that might have changed while mmap_lock was dropped. One thing that might occur, is that the VMA could be resized, and as such, we refetch vma->vm_end to make sure we don't collapse past the end of the VMA. However, it's possible that during this refetch that we expand the region acted on by MADV_COLLAPSE if vma->vm_end is greater than the end of the user-supplied range. Don't expand the acted-on region when refetching vma->vm_end. Fixes: 4d24de9425f7 ("mm: MADV_COLLAPSE: refetch vm_end after reacquiring mmap_lock") Reported-by: Hugh Dickins <hughd@xxxxxxxxxx> Signed-off-by: Zach O'Keefe <zokeefe@xxxxxxxxxx> Cc: Yang Shi <shy828301@xxxxxxxxx> --- mm/khugepaged.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mm/khugepaged.c b/mm/khugepaged.c index 5cb401aa2b9d..b4d2ec0a94ed 100644 --- a/mm/khugepaged.c +++ b/mm/khugepaged.c @@ -2649,7 +2649,7 @@ int madvise_collapse(struct vm_area_struct *vma, struct vm_area_struct **prev, goto out_nolock; } - hend = vma->vm_end & HPAGE_PMD_MASK; + hend = min(hend, vma->vm_end & HPAGE_PMD_MASK); } mmap_assert_locked(mm); memset(cc->node_load, 0, sizeof(cc->node_load)); -- 2.39.0.314.g84b9a713c41-goog