Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

sh: switch to NO_BOOTMEM

Commit 0fa1c579349f ("of/fdt: use memblock_virt_alloc for early alloc")
inadvertently switched the DT unflattening allocations from memblock to
bootmem which doesn't work because the unflattening happens before
bootmem is initialized. Swapping the order of bootmem init and
unflattening could also fix this, but removing bootmem is desired. So
enable NO_BOOTMEM on SH like other architectures have done.

Fixes: 0fa1c579349f ("of/fdt: use memblock_virt_alloc for early alloc")
Reported-by: Rich Felker <dalias@libc.org>
Cc: Yoshinori Sato <ysato@users.sourceforge.jp>
Signed-off-by: Rob Herring <robh@kernel.org>
Signed-off-by: Rich Felker <dalias@libc.org>

authored by

Rob Herring and committed by
Rich Felker
ac21fc2d b9826a49

+7 -82
+1
arch/sh/Kconfig
··· 9 9 select HAVE_IDE if HAS_IOPORT_MAP 10 10 select HAVE_MEMBLOCK 11 11 select HAVE_MEMBLOCK_NODE_MAP 12 + select NO_BOOTMEM 12 13 select ARCH_DISCARD_MEMBLOCK 13 14 select HAVE_OPROFILE 14 15 select HAVE_GENERIC_DMA_COHERENT
-1
arch/sh/kernel/setup.c
··· 11 11 #include <linux/ioport.h> 12 12 #include <linux/init.h> 13 13 #include <linux/initrd.h> 14 - #include <linux/bootmem.h> 15 14 #include <linux/console.h> 16 15 #include <linux/root_dev.h> 17 16 #include <linux/utsname.h>
+6 -62
arch/sh/mm/init.c
··· 211 211 212 212 NODE_DATA(nid) = __va(phys); 213 213 memset(NODE_DATA(nid), 0, sizeof(struct pglist_data)); 214 - 215 - NODE_DATA(nid)->bdata = &bootmem_node_data[nid]; 216 214 #endif 217 215 218 216 NODE_DATA(nid)->node_start_pfn = start_pfn; 219 217 NODE_DATA(nid)->node_spanned_pages = end_pfn - start_pfn; 220 218 } 221 219 222 - static void __init bootmem_init_one_node(unsigned int nid) 223 - { 224 - unsigned long total_pages, paddr; 225 - unsigned long end_pfn; 226 - struct pglist_data *p; 227 - 228 - p = NODE_DATA(nid); 229 - 230 - /* Nothing to do.. */ 231 - if (!p->node_spanned_pages) 232 - return; 233 - 234 - end_pfn = pgdat_end_pfn(p); 235 - 236 - total_pages = bootmem_bootmap_pages(p->node_spanned_pages); 237 - 238 - paddr = memblock_alloc(total_pages << PAGE_SHIFT, PAGE_SIZE); 239 - if (!paddr) 240 - panic("Can't allocate bootmap for nid[%d]\n", nid); 241 - 242 - init_bootmem_node(p, paddr >> PAGE_SHIFT, p->node_start_pfn, end_pfn); 243 - 244 - free_bootmem_with_active_regions(nid, end_pfn); 245 - 246 - /* 247 - * XXX Handle initial reservations for the system memory node 248 - * only for the moment, we'll refactor this later for handling 249 - * reservations in other nodes. 250 - */ 251 - if (nid == 0) { 252 - struct memblock_region *reg; 253 - 254 - /* Reserve the sections we're already using. */ 255 - for_each_memblock(reserved, reg) { 256 - reserve_bootmem(reg->base, reg->size, BOOTMEM_DEFAULT); 257 - } 258 - } 259 - 260 - sparse_memory_present_with_active_regions(nid); 261 - } 262 - 263 220 static void __init do_init_bootmem(void) 264 221 { 265 222 struct memblock_region *reg; 266 - int i; 267 223 268 224 /* Add active regions with valid PFNs. */ 269 225 for_each_memblock(memory, reg) { ··· 235 279 236 280 plat_mem_setup(); 237 281 238 - for_each_online_node(i) 239 - bootmem_init_one_node(i); 282 + for_each_memblock(memory, reg) { 283 + int nid = memblock_get_region_node(reg); 240 284 285 + memory_present(nid, memblock_region_memory_base_pfn(reg), 286 + memblock_region_memory_end_pfn(reg)); 287 + } 241 288 sparse_init(); 242 289 } 243 290 ··· 281 322 { 282 323 unsigned long max_zone_pfns[MAX_NR_ZONES]; 283 324 unsigned long vaddr, end; 284 - int nid; 285 325 286 326 sh_mv.mv_mem_init(); 287 327 ··· 335 377 kmap_coherent_init(); 336 378 337 379 memset(max_zone_pfns, 0, sizeof(max_zone_pfns)); 338 - 339 - for_each_online_node(nid) { 340 - pg_data_t *pgdat = NODE_DATA(nid); 341 - unsigned long low, start_pfn; 342 - 343 - start_pfn = pgdat->bdata->node_min_pfn; 344 - low = pgdat->bdata->node_low_pfn; 345 - 346 - if (max_zone_pfns[ZONE_NORMAL] < low) 347 - max_zone_pfns[ZONE_NORMAL] = low; 348 - 349 - printk("Node %u: start_pfn = 0x%lx, low = 0x%lx\n", 350 - nid, start_pfn, low); 351 - } 352 - 380 + max_zone_pfns[ZONE_NORMAL] = max_low_pfn; 353 381 free_area_init_nodes(max_zone_pfns); 354 382 } 355 383
-19
arch/sh/mm/numa.c
··· 8 8 * for more details. 9 9 */ 10 10 #include <linux/module.h> 11 - #include <linux/bootmem.h> 12 11 #include <linux/memblock.h> 13 12 #include <linux/mm.h> 14 13 #include <linux/numa.h> ··· 25 26 */ 26 27 void __init setup_bootmem_node(int nid, unsigned long start, unsigned long end) 27 28 { 28 - unsigned long bootmap_pages; 29 29 unsigned long start_pfn, end_pfn; 30 - unsigned long bootmem_paddr; 31 30 32 31 /* Don't allow bogus node assignment */ 33 32 BUG_ON(nid >= MAX_NUMNODES || nid <= 0); ··· 45 48 SMP_CACHE_BYTES, end)); 46 49 memset(NODE_DATA(nid), 0, sizeof(struct pglist_data)); 47 50 48 - NODE_DATA(nid)->bdata = &bootmem_node_data[nid]; 49 51 NODE_DATA(nid)->node_start_pfn = start_pfn; 50 52 NODE_DATA(nid)->node_spanned_pages = end_pfn - start_pfn; 51 - 52 - /* Node-local bootmap */ 53 - bootmap_pages = bootmem_bootmap_pages(end_pfn - start_pfn); 54 - bootmem_paddr = memblock_alloc_base(bootmap_pages << PAGE_SHIFT, 55 - PAGE_SIZE, end); 56 - init_bootmem_node(NODE_DATA(nid), bootmem_paddr >> PAGE_SHIFT, 57 - start_pfn, end_pfn); 58 - 59 - free_bootmem_with_active_regions(nid, end_pfn); 60 - 61 - /* Reserve the pgdat and bootmap space with the bootmem allocator */ 62 - reserve_bootmem_node(NODE_DATA(nid), start_pfn << PAGE_SHIFT, 63 - sizeof(struct pglist_data), BOOTMEM_DEFAULT); 64 - reserve_bootmem_node(NODE_DATA(nid), bootmem_paddr, 65 - bootmap_pages << PAGE_SHIFT, BOOTMEM_DEFAULT); 66 53 67 54 /* It's up */ 68 55 node_set_online(nid);