On Mon, Feb 17, 2020 at 02:46:27PM +0900, kkabe@xxxxxxxxxxx wrote: > =========================================== > struct page * __meminit populate_section_memmap(unsigned long pfn, > unsigned long nr_pages, int nid, struct vmem_altmap *altmap) > { > struct page *page, *ret; > unsigned long memmap_size = sizeof(struct page) * PAGES_PER_SECTION; > > page = alloc_pages(GFP_KERNEL|__GFP_NOWARN, get_order(memmap_size)); > if (page) { > goto got_map_page; > } > pr_info("%s: alloc_pages() returned 0x%p (should be 0), reverting to vmalloc(memmap_size=%lu)\n", __func__, page, memmap_size); > BUG_ON(page != 0); > > ret = vmalloc(memmap_size); > pr_info("%s: vmalloc(%lu) returned 0x%p\n", __func__, memmap_size, ret); > if (ret) { > goto got_map_ptr; > } > > return NULL; > got_map_page: > ret = (struct page *)pfn_to_kaddr(page_to_pfn(page)); > pr_info("%s: allocated struct page *page=0x%p\n", __func__, page); > got_map_ptr: > > pr_info("%s: returning struct page * =0x%p\n", __func__, ret); > return ret; > } Could you please replace %p with %px. Wih the first, pointers are hashed so it is trickier to get an overview of the meaning. David could be right about ZONE_NORMAL vs ZONE_HIGHMEM. IIUC, default_kernel_zone_for_pfn and default_zone_for_pfn seem to only deal with (ZONE_DMA,ZONE_NORMAL] or ZONE_MOVABLE. Although I really fail to see how this could cause the crash. Could you also please capture /proc/zoneinfo before and after hotplugging memory? And add this delta on top of your debugging patch? diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c index 0a54ffac8c68..2b9c821d7cf0 100644 --- a/mm/memory_hotplug.c +++ b/mm/memory_hotplug.c @@ -574,6 +574,7 @@ EXPORT_SYMBOL_GPL(restore_online_page_callback); void generic_online_page(struct page *page, unsigned int order) { + pr_info("generic_online_page: page: %px order: %u\n", page, order); kernel_map_pages(page, 1 << order, 1); __free_pages_core(page, order); totalram_pages_add(1UL << order); @@ -774,6 +775,8 @@ int __ref online_pages(unsigned long pfn, unsigned long nr_pages, zone = zone_for_pfn_range(online_type, nid, pfn, nr_pages); move_pfn_range_to_zone(zone, pfn, nr_pages, NULL); + pr_info("%s: pfn: %lx - %lx (zone: %s)\n", __func__, pfn, pfn + nr_pages, zone->name); + arg.start_pfn = pfn; arg.nr_pages = nr_pages; node_states_check_changes_online(nr_pages, zone, &arg); -- Oscar Salvador SUSE L3