• Dave Hansen's avatar
    mm: thp: give transparent hugepage code a separate copy_page · 30b0a105
    Dave Hansen authored
    Right now, the migration code in migrate_page_copy() uses copy_huge_page()
    for hugetlbfs and thp pages:
           if (PageHuge(page) || PageTransHuge(page))
                    copy_huge_page(newpage, page);
    So, yay for code reuse.  But:
      void copy_huge_page(struct page *dst, struct page *src)
            struct hstate *h = page_hstate(src);
    and a non-hugetlbfs page has no page_hstate().  This works 99% of the
    time because page_hstate() determines the hstate from the page order
    alone.  Since the page order of a THP page matches the default hugetlbfs
    page order, it works.
    But, if you change the default huge page size on the boot command-line
    (say default_hugepagesz=1G), then we might not even *have* a 2MB hstate
    so page_hstate() returns null and copy_huge_page() oopses pretty fast
    since copy_huge_page() dereferences the hstate:
      void copy_huge_page(struct page *dst, struct page *src)
            struct hstate *h = page_hstate(src);
            if (unlikely(pages_per_huge_page(h) > MAX_ORDER_NR_PAGES)) {
    Mel noticed that the migration code is really the only user of these
    functions.  This moves all the copy code over to migrate.c and makes
    copy_huge_page() work for THP by checking for it explicitly.
    I believe the bug was introduced in commit b32967ff
     ("mm: numa: Add
    THP migration for the NUMA working set scanning fault case")
    [akpm@linux-foundation.org: fix coding-style and comment text, per Naoya Horiguchi]
    Signed-off-by: default avatarDave Hansen <dave.hansen@linux.intel.com>
    Acked-by: default avatarMel Gorman <mgorman@suse.de>
    Reviewed-by: default avatarNaoya Horiguchi <n-horiguchi@ah.jp.nec.com>
    Cc: Hillf Danton <dhillf@gmail.com>
    Cc: Andrea Arcangeli <aarcange@redhat.com>
    Tested-by: default avatarDave Jiang <dave.jiang@intel.com>
    Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
    Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
hugetlb.h 12.1 KB