Message ID | 1487276034-154065-2-git-send-email-pasha.tatashin@oracle.com |
---|---|
State | Accepted |
Delegated to: | David Miller |
Headers | show |
From: Pavel Tatashin <pasha.tatashin@oracle.com> Date: Thu, 16 Feb 2017 15:13:54 -0500 > In add_node_ranges() when memblock resize happens, the iterator keeps using > the previous freed array. This bug cause hangs on machine where there are > over 128 memory blocks during boot. For example, on machines where memory > interleaving is small. > The problem is seen on T4-4 because it cant have 2T of memory, and memory > is interleaved at 8G. So we have 2T/8G = 256 regions to set node IDs. The > starting size of regions array is 128. Thus, we have to double at least one > time (actually we have to double twice because some memory is already > reserved and thus we need more than 256 regions). We start using an > incorrect pointer to the array after the first doubling. > > Signed-off-by: Pavel Tatashin <pasha.tatashin@oracle.com> > Signed-off-by: Babu Moger <babu.moger@oracle.com> > Reviewed-by: Babu Moger <babu.moger@oracle.com> Applied. -- To unsubscribe from this list: send the line "unsubscribe sparclinux" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c index 5d2f915..3e934f2 100644 --- a/arch/sparc/mm/init_64.c +++ b/arch/sparc/mm/init_64.c @@ -1029,6 +1029,10 @@ int of_node_to_nid(struct device_node *dp) static void __init add_node_ranges(void) { struct memblock_region *reg; + unsigned long prev_max; + +memblock_resized: + prev_max = memblock.memory.max; for_each_memblock(memory, reg) { unsigned long size = reg->size; @@ -1048,6 +1052,8 @@ static void __init add_node_ranges(void) memblock_set_node(start, this_end - start, &memblock.memory, nid); + if (memblock.memory.max != prev_max) + goto memblock_resized; start = this_end; } }