Message ID | 1530099168-31421-1-git-send-email-rppt@linux.vnet.ibm.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On Wed 27-06-18 14:32:48, Mike Rapoport wrote: > Replace bootmem allocator with memblock and enable use of NO_BOOTMEM like > on most other architectures. > > The conversion does not take care of NUMA support which is marked broken > for more than 10 years now. It would be great to describe how is the conversion done. At least on high level.
On Wed, Jun 27, 2018 at 01:38:51PM +0200, Michal Hocko wrote: > On Wed 27-06-18 14:32:48, Mike Rapoport wrote: > > Replace bootmem allocator with memblock and enable use of NO_BOOTMEM like > > on most other architectures. > > > > The conversion does not take care of NUMA support which is marked broken > > for more than 10 years now. > > It would be great to describe how is the conversion done. At least on > high level. It's straightforward, isn't it? :) Sure, no problem. I'll just wait for other feedback before sending v2. > -- > Michal Hocko > SUSE Labs >
Hi Mike, I love your patch! Yet something to improve: [auto build test ERROR on linus/master] [also build test ERROR on v4.18-rc2 next-20180627] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/Mike-Rapoport/alpha-switch-to-NO_BOOTMEM/20180627-194800 config: alpha-allyesconfig (attached as .config) compiler: alpha-linux-gnu-gcc (Debian 7.2.0-11) 7.2.0 reproduce: wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # save the attached .config to linux build tree GCC_VERSION=7.2.0 make.cross ARCH=alpha All error/warnings (new ones prefixed by >>): mm/page_alloc.c: In function 'update_defer_init': >> mm/page_alloc.c:321:14: error: 'PAGES_PER_SECTION' undeclared (first use in this function); did you mean 'USEC_PER_SEC'? (pfn & (PAGES_PER_SECTION - 1)) == 0) { ^~~~~~~~~~~~~~~~~ USEC_PER_SEC mm/page_alloc.c:321:14: note: each undeclared identifier is reported only once for each function it appears in In file included from include/linux/cache.h:5:0, from include/linux/printk.h:9, from include/linux/kernel.h:14, from include/asm-generic/bug.h:18, from arch/alpha/include/asm/bug.h:23, from include/linux/bug.h:5, from include/linux/mmdebug.h:5, from include/linux/mm.h:9, from mm/page_alloc.c:18: mm/page_alloc.c: In function 'deferred_grow_zone': mm/page_alloc.c:1624:52: error: 'PAGES_PER_SECTION' undeclared (first use in this function); did you mean 'USEC_PER_SEC'? unsigned long nr_pages_needed = ALIGN(1 << order, PAGES_PER_SECTION); ^ include/uapi/linux/kernel.h:11:47: note: in definition of macro '__ALIGN_KERNEL_MASK' #define __ALIGN_KERNEL_MASK(x, mask) (((x) + (mask)) & ~(mask)) ^~~~ >> include/linux/kernel.h:58:22: note: in expansion of macro '__ALIGN_KERNEL' #define ALIGN(x, a) __ALIGN_KERNEL((x), (a)) ^~~~~~~~~~~~~~ >> mm/page_alloc.c:1624:34: note: in expansion of macro 'ALIGN' unsigned long nr_pages_needed = ALIGN(1 << order, PAGES_PER_SECTION); ^~~~~ In file included from include/asm-generic/bug.h:18:0, from arch/alpha/include/asm/bug.h:23, from include/linux/bug.h:5, from include/linux/mmdebug.h:5, from include/linux/mm.h:9, from mm/page_alloc.c:18: mm/page_alloc.c: In function 'free_area_init_node': mm/page_alloc.c:6379:50: error: 'PAGES_PER_SECTION' undeclared (first use in this function); did you mean 'USEC_PER_SEC'? pgdat->static_init_pgcnt = min_t(unsigned long, PAGES_PER_SECTION, ^ include/linux/kernel.h:812:22: note: in definition of macro '__typecheck' (!!(sizeof((typeof(x) *)1 == (typeof(y) *)1))) ^ include/linux/kernel.h:836:24: note: in expansion of macro '__safe_cmp' __builtin_choose_expr(__safe_cmp(x, y), \ ^~~~~~~~~~ include/linux/kernel.h:904:27: note: in expansion of macro '__careful_cmp' #define min_t(type, x, y) __careful_cmp((type)(x), (type)(y), <) ^~~~~~~~~~~~~ >> mm/page_alloc.c:6379:29: note: in expansion of macro 'min_t' pgdat->static_init_pgcnt = min_t(unsigned long, PAGES_PER_SECTION, ^~~~~ include/linux/kernel.h:836:2: error: first argument to '__builtin_choose_expr' not a constant __builtin_choose_expr(__safe_cmp(x, y), \ ^ include/linux/kernel.h:904:27: note: in expansion of macro '__careful_cmp' #define min_t(type, x, y) __careful_cmp((type)(x), (type)(y), <) ^~~~~~~~~~~~~ >> mm/page_alloc.c:6379:29: note: in expansion of macro 'min_t' pgdat->static_init_pgcnt = min_t(unsigned long, PAGES_PER_SECTION, ^~~~~ vim +/__ALIGN_KERNEL +58 include/linux/kernel.h 44696908 David S. Miller 2012-05-23 56 3ca45a46 zijun_hu 2016-10-14 57 /* @a is a power of 2 value */ a79ff731 Alexey Dobriyan 2010-04-13 @58 #define ALIGN(x, a) __ALIGN_KERNEL((x), (a)) ed067d4a Krzysztof Kozlowski 2017-04-11 59 #define ALIGN_DOWN(x, a) __ALIGN_KERNEL((x) - ((a) - 1), (a)) 9f93ff5b Alexey Dobriyan 2010-04-13 60 #define __ALIGN_MASK(x, mask) __ALIGN_KERNEL_MASK((x), (mask)) a83308e6 Matthew Wilcox 2007-09-11 61 #define PTR_ALIGN(p, a) ((typeof(p))ALIGN((unsigned long)(p), (a))) f10db627 Herbert Xu 2008-02-06 62 #define IS_ALIGNED(x, a) (((x) & ((typeof(x))(a) - 1)) == 0) 2ea58144 Linus Torvalds 2006-11-26 63 :::::: The code at line 58 was first introduced by commit :::::: a79ff731a1b277d0e92d9453bdf374e04cec717a netfilter: xtables: make XT_ALIGN() usable in exported headers by exporting __ALIGN_KERNEL() :::::: TO: Alexey Dobriyan <adobriyan@gmail.com> :::::: CC: Patrick McHardy <kaber@trash.net> --- 0-DAY kernel test infrastructure Open Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation
On Thu, Jun 28, 2018 at 05:38:29AM +0800, kbuild test robot wrote: > Hi Mike, > > I love your patch! Yet something to improve: > > [auto build test ERROR on linus/master] > [also build test ERROR on v4.18-rc2 next-20180627] > [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] > > url: https://github.com/0day-ci/linux/commits/Mike-Rapoport/alpha-switch-to-NO_BOOTMEM/20180627-194800 > config: alpha-allyesconfig (attached as .config) > compiler: alpha-linux-gnu-gcc (Debian 7.2.0-11) 7.2.0 > reproduce: > wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross > chmod +x ~/bin/make.cross > # save the attached .config to linux build tree > GCC_VERSION=7.2.0 make.cross ARCH=alpha > > All error/warnings (new ones prefixed by >>): > > mm/page_alloc.c: In function 'update_defer_init': > >> mm/page_alloc.c:321:14: error: 'PAGES_PER_SECTION' undeclared (first use in this function); did you mean 'USEC_PER_SEC'? > (pfn & (PAGES_PER_SECTION - 1)) == 0) { > ^~~~~~~~~~~~~~~~~ > USEC_PER_SEC The PAGES_PER_SECTION is defined only for SPARSEMEM with the exception of x86-32 defining it for DISCONTIGMEM as well. That said, any architecture that can have DISCTONTIGMEM=y && NO_BOOTMEM=y will fail the build with DEFERRED_STRUCT_PAGE_INIT enabled. The simplest solution seems to make DEFERRED_STRUCT_PAGE_INIT explicitly dependent on SPARSEMEM rather than !FLATMEM. The downside is that deferred struct page initialization won't be available for x86-32 NUMA setups. Thoughts? > mm/page_alloc.c:321:14: note: each undeclared identifier is reported only once for each function it appears in > In file included from include/linux/cache.h:5:0, > from include/linux/printk.h:9, > from include/linux/kernel.h:14, > from include/asm-generic/bug.h:18, > from arch/alpha/include/asm/bug.h:23, > from include/linux/bug.h:5, > from include/linux/mmdebug.h:5, > from include/linux/mm.h:9, > from mm/page_alloc.c:18: > mm/page_alloc.c: In function 'deferred_grow_zone': > mm/page_alloc.c:1624:52: error: 'PAGES_PER_SECTION' undeclared (first use in this function); did you mean 'USEC_PER_SEC'? > unsigned long nr_pages_needed = ALIGN(1 << order, PAGES_PER_SECTION); > ^ > include/uapi/linux/kernel.h:11:47: note: in definition of macro '__ALIGN_KERNEL_MASK' > #define __ALIGN_KERNEL_MASK(x, mask) (((x) + (mask)) & ~(mask)) > ^~~~ > >> include/linux/kernel.h:58:22: note: in expansion of macro '__ALIGN_KERNEL' > #define ALIGN(x, a) __ALIGN_KERNEL((x), (a)) > ^~~~~~~~~~~~~~ > >> mm/page_alloc.c:1624:34: note: in expansion of macro 'ALIGN' > unsigned long nr_pages_needed = ALIGN(1 << order, PAGES_PER_SECTION); > ^~~~~ > In file included from include/asm-generic/bug.h:18:0, > from arch/alpha/include/asm/bug.h:23, > from include/linux/bug.h:5, > from include/linux/mmdebug.h:5, > from include/linux/mm.h:9, > from mm/page_alloc.c:18: > mm/page_alloc.c: In function 'free_area_init_node': > mm/page_alloc.c:6379:50: error: 'PAGES_PER_SECTION' undeclared (first use in this function); did you mean 'USEC_PER_SEC'? > pgdat->static_init_pgcnt = min_t(unsigned long, PAGES_PER_SECTION, > ^ > include/linux/kernel.h:812:22: note: in definition of macro '__typecheck' > (!!(sizeof((typeof(x) *)1 == (typeof(y) *)1))) > ^ > include/linux/kernel.h:836:24: note: in expansion of macro '__safe_cmp' > __builtin_choose_expr(__safe_cmp(x, y), \ > ^~~~~~~~~~ > include/linux/kernel.h:904:27: note: in expansion of macro '__careful_cmp' > #define min_t(type, x, y) __careful_cmp((type)(x), (type)(y), <) > ^~~~~~~~~~~~~ > >> mm/page_alloc.c:6379:29: note: in expansion of macro 'min_t' > pgdat->static_init_pgcnt = min_t(unsigned long, PAGES_PER_SECTION, > ^~~~~ > include/linux/kernel.h:836:2: error: first argument to '__builtin_choose_expr' not a constant > __builtin_choose_expr(__safe_cmp(x, y), \ > ^ > include/linux/kernel.h:904:27: note: in expansion of macro '__careful_cmp' > #define min_t(type, x, y) __careful_cmp((type)(x), (type)(y), <) > ^~~~~~~~~~~~~ > >> mm/page_alloc.c:6379:29: note: in expansion of macro 'min_t' > pgdat->static_init_pgcnt = min_t(unsigned long, PAGES_PER_SECTION, > ^~~~~ > > vim +/__ALIGN_KERNEL +58 include/linux/kernel.h > > 44696908 David S. Miller 2012-05-23 56 > 3ca45a46 zijun_hu 2016-10-14 57 /* @a is a power of 2 value */ > a79ff731 Alexey Dobriyan 2010-04-13 @58 #define ALIGN(x, a) __ALIGN_KERNEL((x), (a)) > ed067d4a Krzysztof Kozlowski 2017-04-11 59 #define ALIGN_DOWN(x, a) __ALIGN_KERNEL((x) - ((a) - 1), (a)) > 9f93ff5b Alexey Dobriyan 2010-04-13 60 #define __ALIGN_MASK(x, mask) __ALIGN_KERNEL_MASK((x), (mask)) > a83308e6 Matthew Wilcox 2007-09-11 61 #define PTR_ALIGN(p, a) ((typeof(p))ALIGN((unsigned long)(p), (a))) > f10db627 Herbert Xu 2008-02-06 62 #define IS_ALIGNED(x, a) (((x) & ((typeof(x))(a) - 1)) == 0) > 2ea58144 Linus Torvalds 2006-11-26 63 > > :::::: The code at line 58 was first introduced by commit > :::::: a79ff731a1b277d0e92d9453bdf374e04cec717a netfilter: xtables: make XT_ALIGN() usable in exported headers by exporting __ALIGN_KERNEL() > > :::::: TO: Alexey Dobriyan <adobriyan@gmail.com> > :::::: CC: Patrick McHardy <kaber@trash.net> > > --- > 0-DAY kernel test infrastructure Open Source Technology Center > https://lists.01.org/pipermail/kbuild-all Intel Corporation
On Fri 29-06-18 12:24:00, Mike Rapoport wrote: > On Thu, Jun 28, 2018 at 05:38:29AM +0800, kbuild test robot wrote: > > Hi Mike, > > > > I love your patch! Yet something to improve: > > > > [auto build test ERROR on linus/master] > > [also build test ERROR on v4.18-rc2 next-20180627] > > [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] > > > > url: https://github.com/0day-ci/linux/commits/Mike-Rapoport/alpha-switch-to-NO_BOOTMEM/20180627-194800 > > config: alpha-allyesconfig (attached as .config) > > compiler: alpha-linux-gnu-gcc (Debian 7.2.0-11) 7.2.0 > > reproduce: > > wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross > > chmod +x ~/bin/make.cross > > # save the attached .config to linux build tree > > GCC_VERSION=7.2.0 make.cross ARCH=alpha > > > > All error/warnings (new ones prefixed by >>): > > > > mm/page_alloc.c: In function 'update_defer_init': > > >> mm/page_alloc.c:321:14: error: 'PAGES_PER_SECTION' undeclared (first use in this function); did you mean 'USEC_PER_SEC'? > > (pfn & (PAGES_PER_SECTION - 1)) == 0) { > > ^~~~~~~~~~~~~~~~~ > > USEC_PER_SEC > > The PAGES_PER_SECTION is defined only for SPARSEMEM with the exception of > x86-32 defining it for DISCONTIGMEM as well. That said, any architecture > that can have DISCTONTIGMEM=y && NO_BOOTMEM=y will fail the build with > DEFERRED_STRUCT_PAGE_INIT enabled. > > The simplest solution seems to make DEFERRED_STRUCT_PAGE_INIT explicitly > dependent on SPARSEMEM rather than !FLATMEM. The downside is that deferred > struct page initialization won't be available for x86-32 NUMA setups. I am really dubious that 32b systems really need DEFERRED_STRUCT_PAGE_INIT. Regardless of the memory mode. Those systems simply do not have enough memory to bother. Deferred initialization is targeting much larger beasts.
diff --git a/arch/alpha/Kconfig b/arch/alpha/Kconfig index 04a4a138ed13..040692a8d433 100644 --- a/arch/alpha/Kconfig +++ b/arch/alpha/Kconfig @@ -30,6 +30,8 @@ config ALPHA select ODD_RT_SIGACTION select OLD_SIGSUSPEND select CPU_NO_EFFICIENT_FFS if !ALPHA_EV67 + select HAVE_MEMBLOCK + select NO_BOOTMEM help The Alpha is a 64-bit general-purpose processor designed and marketed by the Digital Equipment Corporation of blessed memory, diff --git a/arch/alpha/kernel/core_irongate.c b/arch/alpha/kernel/core_irongate.c index aec757250e07..f70986683fc6 100644 --- a/arch/alpha/kernel/core_irongate.c +++ b/arch/alpha/kernel/core_irongate.c @@ -21,6 +21,7 @@ #include <linux/init.h> #include <linux/initrd.h> #include <linux/bootmem.h> +#include <linux/memblock.h> #include <asm/ptrace.h> #include <asm/cacheflush.h> @@ -241,8 +242,7 @@ albacore_init_arch(void) size / 1024); } #endif - reserve_bootmem_node(NODE_DATA(0), pci_mem, memtop - - pci_mem, BOOTMEM_DEFAULT); + memblock_reserve(pci_mem, memtop - pci_mem); printk("irongate_init_arch: temporarily reserving " "region %08lx-%08lx for PCI\n", pci_mem, memtop - 1); } diff --git a/arch/alpha/kernel/setup.c b/arch/alpha/kernel/setup.c index 5576f7646fb6..4f0d94471bc9 100644 --- a/arch/alpha/kernel/setup.c +++ b/arch/alpha/kernel/setup.c @@ -30,6 +30,7 @@ #include <linux/ioport.h> #include <linux/platform_device.h> #include <linux/bootmem.h> +#include <linux/memblock.h> #include <linux/pci.h> #include <linux/seq_file.h> #include <linux/root_dev.h> @@ -312,9 +313,7 @@ setup_memory(void *kernel_end) { struct memclust_struct * cluster; struct memdesc_struct * memdesc; - unsigned long start_kernel_pfn, end_kernel_pfn; - unsigned long bootmap_size, bootmap_pages, bootmap_start; - unsigned long start, end; + unsigned long kernel_size; unsigned long i; /* Find free clusters, and init and free the bootmem accordingly. */ @@ -322,6 +321,8 @@ setup_memory(void *kernel_end) (hwrpb->mddt_offset + (unsigned long) hwrpb); for_each_mem_cluster(memdesc, cluster, i) { + unsigned long end; + printk("memcluster %lu, usage %01lx, start %8lu, end %8lu\n", i, cluster->usage, cluster->start_pfn, cluster->start_pfn + cluster->numpages); @@ -335,6 +336,9 @@ setup_memory(void *kernel_end) end = cluster->start_pfn + cluster->numpages; if (end > max_low_pfn) max_low_pfn = end; + + memblock_add(PFN_PHYS(cluster->start_pfn), + cluster->numpages << PAGE_SHIFT); } /* @@ -363,87 +367,9 @@ setup_memory(void *kernel_end) max_low_pfn = mem_size_limit; } - /* Find the bounds of kernel memory. */ - start_kernel_pfn = PFN_DOWN(KERNEL_START_PHYS); - end_kernel_pfn = PFN_UP(virt_to_phys(kernel_end)); - bootmap_start = -1; - - try_again: - if (max_low_pfn <= end_kernel_pfn) - panic("not enough memory to boot"); - - /* We need to know how many physically contiguous pages - we'll need for the bootmap. */ - bootmap_pages = bootmem_bootmap_pages(max_low_pfn); - - /* Now find a good region where to allocate the bootmap. */ - for_each_mem_cluster(memdesc, cluster, i) { - if (cluster->usage & 3) - continue; - - start = cluster->start_pfn; - end = start + cluster->numpages; - if (start >= max_low_pfn) - continue; - if (end > max_low_pfn) - end = max_low_pfn; - if (start < start_kernel_pfn) { - if (end > end_kernel_pfn - && end - end_kernel_pfn >= bootmap_pages) { - bootmap_start = end_kernel_pfn; - break; - } else if (end > start_kernel_pfn) - end = start_kernel_pfn; - } else if (start < end_kernel_pfn) - start = end_kernel_pfn; - if (end - start >= bootmap_pages) { - bootmap_start = start; - break; - } - } - - if (bootmap_start == ~0UL) { - max_low_pfn >>= 1; - goto try_again; - } - - /* Allocate the bootmap and mark the whole MM as reserved. */ - bootmap_size = init_bootmem(bootmap_start, max_low_pfn); - - /* Mark the free regions. */ - for_each_mem_cluster(memdesc, cluster, i) { - if (cluster->usage & 3) - continue; - - start = cluster->start_pfn; - end = cluster->start_pfn + cluster->numpages; - if (start >= max_low_pfn) - continue; - if (end > max_low_pfn) - end = max_low_pfn; - if (start < start_kernel_pfn) { - if (end > end_kernel_pfn) { - free_bootmem(PFN_PHYS(start), - (PFN_PHYS(start_kernel_pfn) - - PFN_PHYS(start))); - printk("freeing pages %ld:%ld\n", - start, start_kernel_pfn); - start = end_kernel_pfn; - } else if (end > start_kernel_pfn) - end = start_kernel_pfn; - } else if (start < end_kernel_pfn) - start = end_kernel_pfn; - if (start >= end) - continue; - - free_bootmem(PFN_PHYS(start), PFN_PHYS(end) - PFN_PHYS(start)); - printk("freeing pages %ld:%ld\n", start, end); - } - - /* Reserve the bootmap memory. */ - reserve_bootmem(PFN_PHYS(bootmap_start), bootmap_size, - BOOTMEM_DEFAULT); - printk("reserving pages %ld:%ld\n", bootmap_start, bootmap_start+PFN_UP(bootmap_size)); + /* Reserve the kernel memory. */ + kernel_size = virt_to_phys(kernel_end) - KERNEL_START_PHYS; + memblock_reserve(KERNEL_START_PHYS, kernel_size); #ifdef CONFIG_BLK_DEV_INITRD initrd_start = INITRD_START; @@ -459,8 +385,8 @@ setup_memory(void *kernel_end) initrd_end, phys_to_virt(PFN_PHYS(max_low_pfn))); } else { - reserve_bootmem(virt_to_phys((void *)initrd_start), - INITRD_SIZE, BOOTMEM_DEFAULT); + memblock_reserve(virt_to_phys((void *)initrd_start), + INITRD_SIZE); } } #endif /* CONFIG_BLK_DEV_INITRD */ diff --git a/arch/alpha/mm/numa.c b/arch/alpha/mm/numa.c index a9e86475f169..26cd925d19b1 100644 --- a/arch/alpha/mm/numa.c +++ b/arch/alpha/mm/numa.c @@ -11,6 +11,7 @@ #include <linux/kernel.h> #include <linux/mm.h> #include <linux/bootmem.h> +#include <linux/memblock.h> #include <linux/swap.h> #include <linux/initrd.h> #include <linux/pfn.h> @@ -59,12 +60,10 @@ setup_memory_node(int nid, void *kernel_end) struct memclust_struct * cluster; struct memdesc_struct * memdesc; unsigned long start_kernel_pfn, end_kernel_pfn; - unsigned long bootmap_size, bootmap_pages, bootmap_start; unsigned long start, end; unsigned long node_pfn_start, node_pfn_end; unsigned long node_min_pfn, node_max_pfn; int i; - unsigned long node_datasz = PFN_UP(sizeof(pg_data_t)); int show_init = 0; /* Find the bounds of current node */ @@ -134,24 +133,14 @@ setup_memory_node(int nid, void *kernel_end) /* Cute trick to make sure our local node data is on local memory */ node_data[nid] = (pg_data_t *)(__va(node_min_pfn << PAGE_SHIFT)); #endif - /* Quasi-mark the pg_data_t as in-use */ - node_min_pfn += node_datasz; - if (node_min_pfn >= node_max_pfn) { - printk(" not enough mem to reserve NODE_DATA"); - return; - } - NODE_DATA(nid)->bdata = &bootmem_node_data[nid]; - printk(" Detected node memory: start %8lu, end %8lu\n", node_min_pfn, node_max_pfn); DBGDCONT(" DISCONTIG: node_data[%d] is at 0x%p\n", nid, NODE_DATA(nid)); - DBGDCONT(" DISCONTIG: NODE_DATA(%d)->bdata is at 0x%p\n", nid, NODE_DATA(nid)->bdata); /* Find the bounds of kernel memory. */ start_kernel_pfn = PFN_DOWN(KERNEL_START_PHYS); end_kernel_pfn = PFN_UP(virt_to_phys(kernel_end)); - bootmap_start = -1; if (!nid && (node_max_pfn < end_kernel_pfn || node_min_pfn > start_kernel_pfn)) panic("kernel loaded out of ram"); @@ -161,89 +150,11 @@ setup_memory_node(int nid, void *kernel_end) has much larger alignment than 8Mb, so it's safe. */ node_min_pfn &= ~((1UL << (MAX_ORDER-1))-1); - /* We need to know how many physically contiguous pages - we'll need for the bootmap. */ - bootmap_pages = bootmem_bootmap_pages(node_max_pfn-node_min_pfn); - - /* Now find a good region where to allocate the bootmap. */ - for_each_mem_cluster(memdesc, cluster, i) { - if (cluster->usage & 3) - continue; - - start = cluster->start_pfn; - end = start + cluster->numpages; - - if (start >= node_max_pfn || end <= node_min_pfn) - continue; - - if (end > node_max_pfn) - end = node_max_pfn; - if (start < node_min_pfn) - start = node_min_pfn; - - if (start < start_kernel_pfn) { - if (end > end_kernel_pfn - && end - end_kernel_pfn >= bootmap_pages) { - bootmap_start = end_kernel_pfn; - break; - } else if (end > start_kernel_pfn) - end = start_kernel_pfn; - } else if (start < end_kernel_pfn) - start = end_kernel_pfn; - if (end - start >= bootmap_pages) { - bootmap_start = start; - break; - } - } - - if (bootmap_start == -1) - panic("couldn't find a contiguous place for the bootmap"); - - /* Allocate the bootmap and mark the whole MM as reserved. */ - bootmap_size = init_bootmem_node(NODE_DATA(nid), bootmap_start, - node_min_pfn, node_max_pfn); - DBGDCONT(" bootmap_start %lu, bootmap_size %lu, bootmap_pages %lu\n", - bootmap_start, bootmap_size, bootmap_pages); + memblock_add(PFN_PHYS(node_min_pfn), + (node_max_pfn - node_min_pfn) << PAGE_SHIFT); - /* Mark the free regions. */ - for_each_mem_cluster(memdesc, cluster, i) { - if (cluster->usage & 3) - continue; - - start = cluster->start_pfn; - end = cluster->start_pfn + cluster->numpages; - - if (start >= node_max_pfn || end <= node_min_pfn) - continue; - - if (end > node_max_pfn) - end = node_max_pfn; - if (start < node_min_pfn) - start = node_min_pfn; - - if (start < start_kernel_pfn) { - if (end > end_kernel_pfn) { - free_bootmem_node(NODE_DATA(nid), PFN_PHYS(start), - (PFN_PHYS(start_kernel_pfn) - - PFN_PHYS(start))); - printk(" freeing pages %ld:%ld\n", - start, start_kernel_pfn); - start = end_kernel_pfn; - } else if (end > start_kernel_pfn) - end = start_kernel_pfn; - } else if (start < end_kernel_pfn) - start = end_kernel_pfn; - if (start >= end) - continue; - - free_bootmem_node(NODE_DATA(nid), PFN_PHYS(start), PFN_PHYS(end) - PFN_PHYS(start)); - printk(" freeing pages %ld:%ld\n", start, end); - } - - /* Reserve the bootmap memory. */ - reserve_bootmem_node(NODE_DATA(nid), PFN_PHYS(bootmap_start), - bootmap_size, BOOTMEM_DEFAULT); - printk(" reserving pages %ld:%ld\n", bootmap_start, bootmap_start+PFN_UP(bootmap_size)); + NODE_DATA(nid)->node_start_pfn = node_min_pfn; + NODE_DATA(nid)->node_present_pages = node_max_pfn - node_min_pfn; node_set_online(nid); } @@ -251,6 +162,7 @@ setup_memory_node(int nid, void *kernel_end) void __init setup_memory(void *kernel_end) { + unsigned long kernel_size; int nid; show_mem_layout(); @@ -262,6 +174,9 @@ setup_memory(void *kernel_end) for (nid = 0; nid < MAX_NUMNODES; nid++) setup_memory_node(nid, kernel_end); + kernel_size = virt_to_phys(kernel_end) - KERNEL_START_PHYS; + memblock_reserve(KERNEL_START_PHYS, kernel_size); + #ifdef CONFIG_BLK_DEV_INITRD initrd_start = INITRD_START; if (initrd_start) { @@ -279,9 +194,8 @@ setup_memory(void *kernel_end) phys_to_virt(PFN_PHYS(max_low_pfn))); } else { nid = kvaddr_to_nid(initrd_start); - reserve_bootmem_node(NODE_DATA(nid), - virt_to_phys((void *)initrd_start), - INITRD_SIZE, BOOTMEM_DEFAULT); + memblock_reserve(virt_to_phys((void *)initrd_start), + INITRD_SIZE); } } #endif /* CONFIG_BLK_DEV_INITRD */ @@ -303,9 +217,8 @@ void __init paging_init(void) dma_local_pfn = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT; for_each_online_node(nid) { - bootmem_data_t *bdata = &bootmem_node_data[nid]; - unsigned long start_pfn = bdata->node_min_pfn; - unsigned long end_pfn = bdata->node_low_pfn; + unsigned long start_pfn = NODE_DATA(nid)->node_start_pfn; + unsigned long end_pfn = start_pfn + NODE_DATA(nid)->node_present_pages; if (dma_local_pfn >= end_pfn - start_pfn) zones_size[ZONE_DMA] = end_pfn - start_pfn;
Replace bootmem allocator with memblock and enable use of NO_BOOTMEM like on most other architectures. The conversion does not take care of NUMA support which is marked broken for more than 10 years now. Signed-off-by: Mike Rapoport <rppt@linux.vnet.ibm.com> --- Tested with qemu-system-alpha. I've added some tweaks to sys_dp264 to force memory split for testing with CONFIG_DISCONTIGMEM=y arch/alpha/Kconfig | 2 + arch/alpha/kernel/core_irongate.c | 4 +- arch/alpha/kernel/setup.c | 98 ++++----------------------------- arch/alpha/mm/numa.c | 113 +++++--------------------------------- 4 files changed, 29 insertions(+), 188 deletions(-)