On 10 Dec 2021, at 2:53, Eric Ren wrote: > Hi, > > On 2021/12/10 07:04, Zi Yan wrote: >> From: Zi Yan >> >> alloc_migration_target() is used by alloc_contig_range() and non-LRU >> movable compound pages can be migrated. Current code does not allocate the >> right page size for such pages. Check THP precisely using >> is_transparent_huge() and add allocation support for non-LRU compound >> pages. > Could you elaborate on why the current code doesn't get the right size?  how this patch fixes it. The current code only check PageHuge() and PageTransHuge(). Non-LRU compound pages will be regarded as PageTransHuge() and an order-9 page is always allocated regardless of the actual page order. This patch makes the exact check for THPs using is_transparent_huge() instead of PageTransHuge() and checks PageCompound() after PageHuge() and is_transparent_huge() for non-LRU compound pages. > > The description sounds like it's an existing bug, if so, the patch subject should be changed to > "Fixes ..."? I have not seen any related bug report. > >> >> Signed-off-by: Zi Yan >> --- >> mm/migrate.c | 8 ++++++-- >> 1 file changed, 6 insertions(+), 2 deletions(-) >> >> diff --git a/mm/migrate.c b/mm/migrate.c >> index d487a399253b..2ce3c771b1de 100644 >> --- a/mm/migrate.c >> +++ b/mm/migrate.c >> @@ -1563,7 +1563,7 @@ struct page *alloc_migration_target(struct page *page, unsigned long private) >> return alloc_huge_page_nodemask(h, nid, mtc->nmask, gfp_mask); >> } >> - if (PageTransHuge(page)) { >> + if (is_transparent_hugepage(page)) { >> /* >> * clear __GFP_RECLAIM to make the migration callback >> * consistent with regular THP allocations. >> @@ -1572,13 +1572,17 @@ struct page *alloc_migration_target(struct page *page, unsigned long private) > if (PageTransHuge(page)) {  // just give more code context > ... >> gfp_mask |= GFP_TRANSHUGE; >> order = HPAGE_PMD_ORDER; > order assigned here >> } >> + if (PageCompound(page)) { >> + gfp_mask |= __GFP_COMP; >> + order = compound_order(page); > re-assinged again as THP is a compound page? Ah, you are right. Will use else if instead. Thanks. > Thanks, > Eric >> + } >> zidx = zone_idx(page_zone(page)); >> if (is_highmem_idx(zidx) || zidx == ZONE_MOVABLE) >> gfp_mask |= __GFP_HIGHMEM; >> new_page = __alloc_pages(gfp_mask, order, nid, mtc->nmask); >> - if (new_page && PageTransHuge(new_page)) >> + if (new_page && is_transparent_hugepage(page)) >> prep_transhuge_page(new_page); >> return new_page; -- Best Regards, Yan, Zi