On Fri, Mar 01, 2024 at 10:21:10AM +0000, Ryan Roberts wrote: > > + page_cma = is_migrate_cma_page(page); > > Problem is here: is_migrate_cma_page() is a macro that resolves to this: Ah, yeah, maybe somebody should be testing with CONFIG_CMA enabled. Ahem. > page_cma = get_pfnblock_flags_mask(page, page_to_pfn(page), MIGRATETYPE_MASK) == MIGRATE_CMA; > > And since page is on the stack, page_to_pfn() gives a very wrong answer. > > I confirmed that the problem goes away for both cases above, when changing the line to: > > page_cma = get_pfnblock_flags_mask(page, pfn, MIGRATETYPE_MASK) == MIGRATE_CMA; Thanks! I think what we end up wanting is ... >From f005189ad418d05d168c0ff00daecc2a444733ef Mon Sep 17 00:00:00 2001 From: "Matthew Wilcox (Oracle)" <willy@xxxxxxxxxxxxx> Date: Fri, 1 Mar 2024 16:11:20 -0500 Subject: [PATCH] mm: Fix __dump_folio Ryan Roberts reports that (if you have CONFIG_CMA enabled), calling __dump_folio() will panic as we call is_migrate_cma_page() with a stack copy of struct page, which gets passed to page_to_pfn(). Signed-off-by: Matthew Wilcox (Oracle) <willy@xxxxxxxxxxxxx> --- include/linux/mmzone.h | 3 +++ mm/debug.c | 4 +--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h index 633812a1d220..c11b7cde81ef 100644 --- a/include/linux/mmzone.h +++ b/include/linux/mmzone.h @@ -76,9 +76,12 @@ extern const char * const migratetype_names[MIGRATE_TYPES]; #ifdef CONFIG_CMA # define is_migrate_cma(migratetype) unlikely((migratetype) == MIGRATE_CMA) # define is_migrate_cma_page(_page) (get_pageblock_migratetype(_page) == MIGRATE_CMA) +# define is_migrate_cma_folio(folio, pfn) (MIGRATE_CMA == \ + get_pfnblock_flags_mask(&folio->page, pfn, MIGRATETYPE_MASK)) #else # define is_migrate_cma(migratetype) false # define is_migrate_cma_page(_page) false +# define is_migrate_cma_folio(folio, pfn) false #endif static inline bool is_migrate_movable(int mt) diff --git a/mm/debug.c b/mm/debug.c index 32ac7d79fd04..e7aa8a9d5d86 100644 --- a/mm/debug.c +++ b/mm/debug.c @@ -55,7 +55,6 @@ static void __dump_folio(struct folio *folio, struct page *page, unsigned long pfn, unsigned long idx) { struct address_space *mapping = folio_mapping(folio); - bool page_cma; int mapcount = 0; char *type = ""; @@ -98,9 +97,8 @@ static void __dump_folio(struct folio *folio, struct page *page, * state for debugging, it should be fine to accept a bit of * inaccuracy here due to racing. */ - page_cma = is_migrate_cma_page(page); pr_warn("%sflags: %pGp%s\n", type, &folio->flags, - page_cma ? " CMA" : ""); + is_migrate_cma_folio(folio, pfn) ? " CMA" : ""); pr_warn("page_type: %pGt\n", &folio->page.page_type); print_hex_dump(KERN_WARNING, "raw: ", DUMP_PREFIX_NONE, 32, -- 2.43.0