Hi: On 2021/12/17 14:25, Li Xinhai wrote: > When BUG_ON check for THP migration entry, the existing code only check > thp_migration_supported case, but not for !thp_migration_supported case. > If !thp_migration_supported() and !pmd_present(), the original code may > dead loop in theory. To make the BUG_ON check consistent, we need catch > both cases. > > Move the BUG_ON check one step earlier, because if the bug happen we > should know it instead of depend on FOLL_MIGRATION been used by caller. > > Because pmdval instead of *pmd is read by the is_pmd_migration_entry() > check, the existing code don't help to avoid useless locking within > pmd_migration_entry_wait(), so remove that check. Thanks for the patch. Looks good to me. Reviewed-by: Miaohe Lin <linmiaohe@xxxxxxxxxx> BTW, there might be a similar scenario in __handle_mm_fault: diff --git a/mm/memory.c b/mm/memory.c index 514a81cdd1ae..fb5e12f22e15 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -4659,10 +4659,9 @@ static vm_fault_t __handle_mm_fault(struct vm_area_struct *vma, barrier(); if (unlikely(is_swap_pmd(vmf.orig_pmd))) { - VM_BUG_ON(thp_migration_supported() && + VM_BUG_ON(!thp_migration_supported() || !is_pmd_migration_entry(vmf.orig_pmd)); - if (is_pmd_migration_entry(vmf.orig_pmd)) - pmd_migration_entry_wait(mm, vmf.pmd); + pmd_migration_entry_wait(mm, vmf.pmd); return 0; } if (pmd_trans_huge(vmf.orig_pmd) || pmd_devmap(vmf.orig_pmd)) { If !thp_migration_supported() and !pmd_present(), we might also dead loop here if I do not miss anything. Maybe you could help fix this too. Many thanks anyway. > > Signed-off-by: Li Xinhai <lixinhai.lxh@xxxxxxxxx> > Cc: Zi Yan <ziy@xxxxxxxxxx> > Cc: "Huang, Ying" <ying.huang@xxxxxxxxx> > Cc: "Kirill A. Shutemov" <kirill.shutemov@xxxxxxxxxxxxxxx> > --- > V3->V4: > Fix typos > > V2->V3: > mention about the dead loop in commit message. > > V1->V2: > Move the BUG_ON() check before if(!(flags & FOLL_MIGRATION)); and add comments > for it. > > mm/gup.c | 13 +++++++++---- > 1 file changed, 9 insertions(+), 4 deletions(-) > > diff --git a/mm/gup.c b/mm/gup.c > index 2c51e9748a6a..1b500ca2a1b8 100644 > --- a/mm/gup.c > +++ b/mm/gup.c > @@ -642,12 +642,17 @@ static struct page *follow_pmd_mask(struct vm_area_struct *vma, > } > retry: > if (!pmd_present(pmdval)) { > + /* > + * Should never reach here, if thp migration is not supported; > + * Otherwise, it must be a thp migration entry. > + */ > + VM_BUG_ON(!thp_migration_supported() || > + !is_pmd_migration_entry(pmdval)); > + > if (likely(!(flags & FOLL_MIGRATION))) > return no_page_table(vma, flags); > - VM_BUG_ON(thp_migration_supported() && > - !is_pmd_migration_entry(pmdval)); > - if (is_pmd_migration_entry(pmdval)) > - pmd_migration_entry_wait(mm, pmd); > + > + pmd_migration_entry_wait(mm, pmd); > pmdval = READ_ONCE(*pmd); > /* > * MADV_DONTNEED may convert the pmd to null because >