Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751395AbeAGFPG convert rfc822-to-8bit (ORCPT + 1 other); Sun, 7 Jan 2018 00:15:06 -0500 Received: from mout.gmx.net ([212.227.17.20]:61778 "EHLO mout.gmx.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751025AbeAGFPE (ORCPT ); Sun, 7 Jan 2018 00:15:04 -0500 Message-ID: <1515302062.6507.18.camel@gmx.de> Subject: Re: [PATCH 4.14 023/159] mm/sparsemem: Allocate mem_section at runtime for CONFIG_SPARSEMEM_EXTREME=y From: Mike Galbraith To: Greg Kroah-Hartman , linux-kernel@vger.kernel.org Cc: stable@vger.kernel.org, "Kirill A. Shutemov" , Andrew Morton , Andy Lutomirski , Borislav Petkov , Cyrill Gorcunov , Linus Torvalds , Peter Zijlstra , Thomas Gleixner , linux-mm@kvack.org, Ingo Molnar Date: Sun, 07 Jan 2018 06:14:22 +0100 In-Reply-To: <20171222084625.007160464@linuxfoundation.org> References: <20171222084623.668990192@linuxfoundation.org> <20171222084625.007160464@linuxfoundation.org> Content-Type: text/plain; charset="ISO-8859-15" X-Mailer: Evolution 3.20.5 Mime-Version: 1.0 Content-Transfer-Encoding: 8BIT X-Provags-ID: V03:K0:LY2TazRnDck/YThC4zGKmBBdyGLQkhjxXlM0VQN354ZU1KIjjAc A5C5X7lr0sjkis87DKnt4PTvZPMh1VB9XCG2E1uwI1hQtoHQX7IPG5u9PARK3+b8Y/khB3+ f7TAlfw719iUoBNvkoC+xzzYKj8onf76OvQkuXY2TzZbup3nF9Teo0JdEddCQHuk0KP504z DlSoGyyt2QfN6OBTl31zw== X-UI-Out-Filterresults: notjunk:1;V01:K0:RczIddKTHl4=:i0YoevE6X3sgzv9LGS90kF XwypF2FFovPxPTun9gYRIfulmntQS4/WBhSxBFmSppLDU9GuEBdIdOpl8AGXFbJMD/vgbIkbg 6wyfHn8i7k8GjdWbG9Xa29PYq/D+hyCMBH22ex19gZ92POFSqh8vWTkK8Q+YvblO70UGXhs6k wEDE6bvhHhDXiUjxhxVDt/Wz6+B+ke5yMfEYvbKn+uTMAldC3xzKGgeidGomvhfVV3vUzEaDo dFQbh0RmLYkRt2St6qTIvhPLzqvygwFLVZQUD+9OIhPHqV2lEarKdJmnOqZGsDu3S9nAO5Is9 fhQ9gmXuDgk6tRVntyrZU0uD9+wumNJIKhpnXXkAfOJhJrhzXLFRmYQ5pH9RPxuqJPRl0TTuE Q/5JC3vWoRyRwbR4VcwmGmcVEIyquy2ihvL68yzpFLeWLyDpgSJNbAWe5C1hFA9bxMiTNJ5/U zsvcijyywQUQ6YDbBS8hrnjcHUQaZIpprfxt2x3dFZzzL/9HcOqxK1z8LvMEyscgtTdNxeuKm VV794csSMlVEZM4vSXWt7iFjT5+CXFpufRnr2Pqk6ququRoYbhtx5f7QYZMkCa9zOa82MsYP4 4l+03Mch6zZrpSEyu4JWTGOmZdT5MoLRqTdEuoQvZJ6matTPlr+Jxwzu1DkwDMF3vyCaurlDW l9SsNvBBFEd2pPoMKr0FmYobOObeFd+cGgNkFfQqtxNfdQd8txM46BLa++1rHn12JpmO4JSt+ RP8iL+i11sGGIbpzA/A4BlO5PGTdoYH9j+p7h5U+khnKGiNQzwA5e/ExAE2ReLLVOeaYOoJez +XOqZkDGOzGES2ygaoPn3XZ5rF4nLtMndJoAR7CAgz0kaycnbc= Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Return-Path: On Fri, 2017-12-22 at 09:45 +0100, Greg Kroah-Hartman wrote: > 4.14-stable review patch. If anyone has any objections, please let me know. FYI, this broke kdump, or rather the makedumpfile part thereof. ?Forward looking wreckage is par for the kdump course, but... > ------------------ > > From: Kirill A. Shutemov > > commit 83e3c48729d9ebb7af5a31a504f3fd6aff0348c4 upstream. > > Size of the mem_section[] array depends on the size of the physical address space. > > In preparation for boot-time switching between paging modes on x86-64 > we need to make the allocation of mem_section[] dynamic, because otherwise > we waste a lot of RAM: with CONFIG_NODE_SHIFT=10, mem_section[] size is 32kB > for 4-level paging and 2MB for 5-level paging mode. > > The patch allocates the array on the first call to sparse_memory_present_with_active_regions(). > > Signed-off-by: Kirill A. Shutemov > Cc: Andrew Morton > Cc: Andy Lutomirski > Cc: Borislav Petkov > Cc: Cyrill Gorcunov > Cc: Linus Torvalds > Cc: Peter Zijlstra > Cc: Thomas Gleixner > Cc: linux-mm@kvack.org > Link: http://lkml.kernel.org/r/20170929140821.37654-2-kirill.shutemov@linux.intel.com > Signed-off-by: Ingo Molnar > Signed-off-by: Greg Kroah-Hartman > > --- > include/linux/mmzone.h | 6 +++++- > mm/page_alloc.c | 10 ++++++++++ > mm/sparse.c | 17 +++++++++++------ > 3 files changed, 26 insertions(+), 7 deletions(-) > > --- a/include/linux/mmzone.h > +++ b/include/linux/mmzone.h > @@ -1152,13 +1152,17 @@ struct mem_section { > #define SECTION_ROOT_MASK (SECTIONS_PER_ROOT - 1) > > #ifdef CONFIG_SPARSEMEM_EXTREME > -extern struct mem_section *mem_section[NR_SECTION_ROOTS]; > +extern struct mem_section **mem_section; > #else > extern struct mem_section mem_section[NR_SECTION_ROOTS][SECTIONS_PER_ROOT]; > #endif > > static inline struct mem_section *__nr_to_section(unsigned long nr) > { > +#ifdef CONFIG_SPARSEMEM_EXTREME > + if (!mem_section) > + return NULL; > +#endif > if (!mem_section[SECTION_NR_TO_ROOT(nr)]) > return NULL; > return &mem_section[SECTION_NR_TO_ROOT(nr)][nr & SECTION_ROOT_MASK]; > --- a/mm/page_alloc.c > +++ b/mm/page_alloc.c > @@ -5651,6 +5651,16 @@ void __init sparse_memory_present_with_a > unsigned long start_pfn, end_pfn; > int i, this_nid; > > +#ifdef CONFIG_SPARSEMEM_EXTREME > + if (!mem_section) { > + unsigned long size, align; > + > + size = sizeof(struct mem_section) * NR_SECTION_ROOTS; > + align = 1 << (INTERNODE_CACHE_SHIFT); > + mem_section = memblock_virt_alloc(size, align); > + } > +#endif > + > for_each_mem_pfn_range(i, nid, &start_pfn, &end_pfn, &this_nid) > memory_present(this_nid, start_pfn, end_pfn); > } > --- a/mm/sparse.c > +++ b/mm/sparse.c > @@ -23,8 +23,7 @@ > * 1) mem_section - memory sections, mem_map's for valid memory > */ > #ifdef CONFIG_SPARSEMEM_EXTREME > -struct mem_section *mem_section[NR_SECTION_ROOTS] > - ____cacheline_internodealigned_in_smp; > +struct mem_section **mem_section; > #else > struct mem_section mem_section[NR_SECTION_ROOTS][SECTIONS_PER_ROOT] > ____cacheline_internodealigned_in_smp; > @@ -101,7 +100,7 @@ static inline int sparse_index_init(unsi > int __section_nr(struct mem_section* ms) > { > unsigned long root_nr; > - struct mem_section* root; > + struct mem_section *root = NULL; > > for (root_nr = 0; root_nr < NR_SECTION_ROOTS; root_nr++) { > root = __nr_to_section(root_nr * SECTIONS_PER_ROOT); > @@ -112,7 +111,7 @@ int __section_nr(struct mem_section* ms) > break; > } > > - VM_BUG_ON(root_nr == NR_SECTION_ROOTS); > + VM_BUG_ON(!root); > > return (root_nr * SECTIONS_PER_ROOT) + (ms - root); > } > @@ -330,11 +329,17 @@ again: > static void __init check_usemap_section_nr(int nid, unsigned long *usemap) > { > unsigned long usemap_snr, pgdat_snr; > - static unsigned long old_usemap_snr = NR_MEM_SECTIONS; > - static unsigned long old_pgdat_snr = NR_MEM_SECTIONS; > + static unsigned long old_usemap_snr; > + static unsigned long old_pgdat_snr; > struct pglist_data *pgdat = NODE_DATA(nid); > int usemap_nid; > > + /* First call */ > + if (!old_usemap_snr) { > + old_usemap_snr = NR_MEM_SECTIONS; > + old_pgdat_snr = NR_MEM_SECTIONS; > + } > + > usemap_snr = pfn_to_section_nr(__pa(usemap) >> PAGE_SHIFT); > pgdat_snr = pfn_to_section_nr(__pa(pgdat) >> PAGE_SHIFT); > if (usemap_snr == pgdat_snr) > >