--- x/mm/rmap.c +++ y/mm/rmap.c @@ -2283,6 +2283,7 @@ static bool try_to_migrate_one(struct fo struct mm_struct *mm = vma->vm_mm; DEFINE_FOLIO_VMA_WALK(pvmw, folio, vma, address, 0); bool anon_exclusive, writable, ret = true; + int check_excl = 1; pte_t pteval; struct page *subpage; struct mmu_notifier_range range; @@ -2422,6 +2423,7 @@ static bool try_to_migrate_one(struct fo if (pte_dirty(pteval)) folio_mark_dirty(folio); writable = pte_write(pteval); + check_excl = 0; } else if (likely(pte_present(pteval))) { flush_cache_page(vma, address, pfn); /* Nuke the page table entry. */ @@ -2446,10 +2448,17 @@ static bool try_to_migrate_one(struct fo } else { pte_clear(mm, address, pvmw.pte); writable = is_writable_device_private_entry(pte_to_swp_entry(pteval)); + check_excl = 0; } - VM_WARN_ON_FOLIO(writable && folio_test_anon(folio) && - !anon_exclusive, folio); + if (check_excl) { + pfn = pte_pfn(pteval); + subpage = folio_page(folio, pfn - folio_pfn(folio)); + anon_exclusive = folio_test_anon(folio) && + PageAnonExclusive(subpage); + VM_WARN_ON_FOLIO(writable && folio_test_anon(folio) && + !anon_exclusive, folio); + } /* Update high watermark before we lower rss */ update_hiwater_rss(mm);