On Mon, Aug 24, 2015 at 4:41 PM, Yinghai Lu <yinghai@xxxxxxxxxx> wrote: > On Mon, Aug 24, 2015 at 3:39 PM, Tony Luck <tony.luck@xxxxxxxxx> wrote: >> On Mon, Aug 24, 2015 at 2:25 PM, Yinghai Lu <yinghai@xxxxxxxxxx> wrote: >> >>> Can you boot with "debug ignore_loglevel" so we can see following print out >>> for vmemmap? >> >> See attached. There are a few extra messages from my own debug printk() >> calls. It seems that we successfully deal with node 0 from topology_init() >> but die walking node 1. I see that the NODE_DATA limits for memory >> on node 1 were from 1d70000 to 3a00000. But when we get into >> register_mem_sect_under_node() we have rounded the start pfn down to >> 1d00000 ... and we panic processing that range (which is in a hole in e820). >> >> We seem to die here: >> >> for (pfn = sect_start_pfn; pfn <= sect_end_pfn; pfn++) { >> int page_nid; >> >> page_nid = get_nid_for_pfn(pfn); > > oh, no. > register_mem_sect_under_node() is assuming: > first section in the block is present and first page in that section is present. attached should fix the problem:
diff --git a/drivers/base/node.c b/drivers/base/node.c index 31df474d..cc910ad 100644 --- a/drivers/base/node.c +++ b/drivers/base/node.c @@ -390,8 +390,14 @@ int register_mem_sect_under_node(struct memory_block *mem_blk, int nid) sect_end_pfn = section_nr_to_pfn(mem_blk->end_section_nr); sect_end_pfn += PAGES_PER_SECTION - 1; for (pfn = sect_start_pfn; pfn <= sect_end_pfn; pfn++) { - int page_nid; + int page_nid, scn_nr; + scn_nr = pfn_to_section_nr(pfn); + if (!present_section_nr(scn_nr)) { + pfn = round_down(pfn + PAGES_PER_SECTION, + PAGES_PER_SECTION) - 1; + continue; + } page_nid = get_nid_for_pfn(pfn); if (page_nid < 0) continue; @@ -426,10 +432,18 @@ int unregister_mem_sect_under_nodes(struct memory_block *mem_blk, return -ENOMEM; nodes_clear(*unlinked_nodes); - sect_start_pfn = section_nr_to_pfn(phys_index); - sect_end_pfn = sect_start_pfn + PAGES_PER_SECTION - 1; + sect_start_pfn = section_nr_to_pfn(mem_blk->start_section_nr); + sect_end_pfn = section_nr_to_pfn(mem_blk->end_section_nr); + sect_end_pfn += PAGES_PER_SECTION - 1; for (pfn = sect_start_pfn; pfn <= sect_end_pfn; pfn++) { - int nid; + int nid, scn_nr; + + scn_nr = pfn_to_section_nr(pfn); + if (!present_section_nr(scn_nr)) { + pfn = round_down(pfn + PAGES_PER_SECTION, + PAGES_PER_SECTION) - 1; + continue; + } nid = get_nid_for_pfn(pfn); if (nid < 0)