aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKirill A. Shutemov <kirill.shutemov@linux.intel.com>2017-11-07 03:33:37 -0500
committerIngo Molnar <mingo@kernel.org>2017-11-07 05:16:08 -0500
commit629a359bdb0e0652a8227b4ff3125431995fec6e (patch)
tree4cc7f4e4bec511139adf89bd7ee9081052b7750d
parent15670bfe19905b1dcbb63137f40d718b59d84479 (diff)
mm/sparsemem: Fix ARM64 boot crash when CONFIG_SPARSEMEM_EXTREME=y
Since commit: 83e3c48729d9 ("mm/sparsemem: Allocate mem_section at runtime for CONFIG_SPARSEMEM_EXTREME=y") we allocate the mem_section array dynamically in sparse_memory_present_with_active_regions(), but some architectures, like arm64, don't call the routine to initialize sparsemem. Let's move the initialization into memory_present() it should cover all architectures. Reported-and-tested-by: Sudeep Holla <sudeep.holla@arm.com> Tested-by: Bjorn Andersson <bjorn.andersson@linaro.org> Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com> Acked-by: Will Deacon <will.deacon@arm.com> Cc: Andrew Morton <akpm@linux-foundation.org> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: linux-mm@kvack.org Fixes: 83e3c48729d9 ("mm/sparsemem: Allocate mem_section at runtime for CONFIG_SPARSEMEM_EXTREME=y") Link: http://lkml.kernel.org/r/20171107083337.89952-1-kirill.shutemov@linux.intel.com Signed-off-by: Ingo Molnar <mingo@kernel.org>
-rw-r--r--mm/page_alloc.c10
-rw-r--r--mm/sparse.c10
2 files changed, 10 insertions, 10 deletions
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 8dfd13f724d9..77e4d3c5c57b 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -5646,16 +5646,6 @@ void __init sparse_memory_present_with_active_regions(int nid)
5646 unsigned long start_pfn, end_pfn; 5646 unsigned long start_pfn, end_pfn;
5647 int i, this_nid; 5647 int i, this_nid;
5648 5648
5649#ifdef CONFIG_SPARSEMEM_EXTREME
5650 if (!mem_section) {
5651 unsigned long size, align;
5652
5653 size = sizeof(struct mem_section) * NR_SECTION_ROOTS;
5654 align = 1 << (INTERNODE_CACHE_SHIFT);
5655 mem_section = memblock_virt_alloc(size, align);
5656 }
5657#endif
5658
5659 for_each_mem_pfn_range(i, nid, &start_pfn, &end_pfn, &this_nid) 5649 for_each_mem_pfn_range(i, nid, &start_pfn, &end_pfn, &this_nid)
5660 memory_present(this_nid, start_pfn, end_pfn); 5650 memory_present(this_nid, start_pfn, end_pfn);
5661} 5651}
diff --git a/mm/sparse.c b/mm/sparse.c
index b00a97398795..d294148ba395 100644
--- a/mm/sparse.c
+++ b/mm/sparse.c
@@ -206,6 +206,16 @@ void __init memory_present(int nid, unsigned long start, unsigned long end)
206{ 206{
207 unsigned long pfn; 207 unsigned long pfn;
208 208
209#ifdef CONFIG_SPARSEMEM_EXTREME
210 if (unlikely(!mem_section)) {
211 unsigned long size, align;
212
213 size = sizeof(struct mem_section) * NR_SECTION_ROOTS;
214 align = 1 << (INTERNODE_CACHE_SHIFT);
215 mem_section = memblock_virt_alloc(size, align);
216 }
217#endif
218
209 start &= PAGE_SECTION_MASK; 219 start &= PAGE_SECTION_MASK;
210 mminit_validate_memmodel_limits(&start, &end); 220 mminit_validate_memmodel_limits(&start, &end);
211 for (pfn = start; pfn < end; pfn += PAGES_PER_SECTION) { 221 for (pfn = start; pfn < end; pfn += PAGES_PER_SECTION) {