From: Zi Yan <z...@nvidia.com>

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.

Signed-off-by: Zi Yan <z...@nvidia.com>
---
 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)
                gfp_mask |= GFP_TRANSHUGE;
                order = HPAGE_PMD_ORDER;
        }
+       if (PageCompound(page)) {
+               gfp_mask |= __GFP_COMP;
+               order = compound_order(page);
+       }
        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;
-- 
2.33.0

Reply via email to