mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-09-10 15:49:01 -04:00
mm: fix incorrect vm_flags usage when checking allowable orders for tmpfs
Lance reported that when nothing else causes the mm to be considered for khugepaged collapse, an MADV_HUGEPAGE-advised tmpfs VMA alone does not trigger scanning. After commit6beeab870e("mm: shmem: move shmem_huge_global_enabled() into shmem_allowable_huge_orders()"), the shmem/tmpfs allowable order check reads vma->flags directly. However, when MADV_HUGEPAGE is handled, khugepaged_enter_vma() is called before the VMA's flags have been updated, so the check uses stale flags and incorrectly rejects the VMA for collapse. As a result, khugepaged does not collapse the tmpfs file into PMD order in time. Fix this by calling khugepaged_enter_vma() with the new VMA flags in madvise_update_vma(). Meanwhile we can remove the khugepaged_enter_vma() in hugepage_madvise(). Link: https://lore.kernel.org/7d5b5eb27be798f89d563b06254c947ff53db0b2.1787020910.git.baolin.wang@linux.alibaba.com Fixes:6beeab870e("mm: shmem: move shmem_huge_global_enabled() into shmem_allowable_huge_orders()") Signed-off-by: Baolin Wang <baolin.wang@linux.alibaba.com> Reported-by: Lance Yang <lance.yang@linux.dev> Closes: https://lore.kernel.org/all/20260815181632.21453-1-lance.yang@linux.dev/ Suggested-by: Lorenzo Stoakes (ARM) <ljs@kernel.org> Reviewed-by: Zi Yan <ziy@nvidia.com> Reviewed-by: Lorenzo Stoakes (ARM) <ljs@kernel.org> Cc: Barry Song <baohua@kernel.org> Cc: David Hildenbrand <david@kernel.org> Cc: Dev Jain <dev.jain@arm.com> Cc: Hugh Dickins <hughd@google.com> Cc: Lance Yang <lance.yang@linux.dev> Cc: Liam R. Howlett <liam@infradead.org> Cc: Ryan Roberts <ryan.roberts@arm.com> Cc: Vlastimil Babka <vbabka@kernel.org> Cc: <stable@vger.kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
This commit is contained in:
committed by
Andrew Morton
parent
267bede12d
commit
2fd4e76936
@@ -454,12 +454,6 @@ int hugepage_madvise(struct vm_area_struct *vma,
|
||||
case MADV_HUGEPAGE:
|
||||
*vm_flags &= ~VM_NOHUGEPAGE;
|
||||
*vm_flags |= VM_HUGEPAGE;
|
||||
/*
|
||||
* If the vma become good for khugepaged to scan,
|
||||
* register it here without waiting a page fault that
|
||||
* may not happen any time soon.
|
||||
*/
|
||||
khugepaged_enter_vma(vma, *vm_flags);
|
||||
break;
|
||||
case MADV_NOHUGEPAGE:
|
||||
*vm_flags &= ~VM_HUGEPAGE;
|
||||
|
||||
@@ -178,6 +178,14 @@ static int madvise_update_vma(vm_flags_t new_flags,
|
||||
/* vm_flags is protected by the mmap_lock held in write mode. */
|
||||
vma_start_write(vma);
|
||||
vma->flags = new_vma_flags;
|
||||
/*
|
||||
* If the vma become good for khugepaged to scan,
|
||||
* register it here without waiting a page fault that
|
||||
* may not happen any time soon.
|
||||
*/
|
||||
if (vma_flags_test(&new_vma_flags, VMA_HUGEPAGE_BIT))
|
||||
khugepaged_enter_vma(vma, vma_flags_to_legacy(new_vma_flags));
|
||||
|
||||
if (set_new_anon_name)
|
||||
return replace_anon_vma_name(vma, anon_name);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user