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

mm: remove sparsemem allocation details from the bootmem allocator

alloc_bootmem_section() derives allocation area constraints from the
specified sparsemem section. This is a bit specific for a generic memory
allocator like bootmem, though, so move it over to sparsemem.

As __alloc_bootmem_node_nopanic() already retries failed allocations with
relaxed area constraints, the fallback code in sparsemem.c can be removed
and the code becomes a bit more compact overall.

[akpm@linux-foundation.org: fix build]
Signed-off-by: Johannes Weiner <hannes@cmpxchg.org>
Acked-by: Tejun Heo <tj@kernel.org>
Acked-by: David S. Miller <davem@davemloft.net>
Cc: Yinghai Lu <yinghai@kernel.org>
Cc: Gavin Shan <shangw@linux.vnet.ibm.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Johannes Weiner and committed by
Linus Torvalds
238305bb e9079911

+12 -60
-3
include/linux/bootmem.h
··· 135 135 extern int reserve_bootmem_generic(unsigned long addr, unsigned long size, 136 136 int flags); 137 137 138 - extern void *alloc_bootmem_section(unsigned long size, 139 - unsigned long section_nr); 140 - 141 138 #ifdef CONFIG_HAVE_ARCH_ALLOC_REMAP 142 139 extern void *alloc_remap(int nid, unsigned long size); 143 140 #else
-22
mm/bootmem.c
··· 803 803 804 804 } 805 805 806 - #ifdef CONFIG_SPARSEMEM 807 - /** 808 - * alloc_bootmem_section - allocate boot memory from a specific section 809 - * @size: size of the request in bytes 810 - * @section_nr: sparse map section to allocate from 811 - * 812 - * Return NULL on failure. 813 - */ 814 - void * __init alloc_bootmem_section(unsigned long size, 815 - unsigned long section_nr) 816 - { 817 - bootmem_data_t *bdata; 818 - unsigned long pfn, goal; 819 - 820 - pfn = section_nr_to_pfn(section_nr); 821 - goal = pfn << PAGE_SHIFT; 822 - bdata = &bootmem_node_data[early_pfn_to_nid(pfn)]; 823 - 824 - return alloc_bootmem_bdata(bdata, size, SMP_CACHE_BYTES, goal, 0); 825 - } 826 - #endif 827 - 828 806 #ifndef ARCH_LOW_ADDRESS_LIMIT 829 807 #define ARCH_LOW_ADDRESS_LIMIT 0xffffffffUL 830 808 #endif
-22
mm/nobootmem.c
··· 355 355 return __alloc_bootmem_node(pgdat, size, align, goal); 356 356 } 357 357 358 - #ifdef CONFIG_SPARSEMEM 359 - /** 360 - * alloc_bootmem_section - allocate boot memory from a specific section 361 - * @size: size of the request in bytes 362 - * @section_nr: sparse map section to allocate from 363 - * 364 - * Return NULL on failure. 365 - */ 366 - void * __init alloc_bootmem_section(unsigned long size, 367 - unsigned long section_nr) 368 - { 369 - unsigned long pfn, goal, limit; 370 - 371 - pfn = section_nr_to_pfn(section_nr); 372 - goal = pfn << PAGE_SHIFT; 373 - limit = section_nr_to_pfn(section_nr + 1) << PAGE_SHIFT; 374 - 375 - return __alloc_memory_core_early(early_pfn_to_nid(pfn), size, 376 - SMP_CACHE_BYTES, goal, limit); 377 - } 378 - #endif 379 - 380 358 #ifndef ARCH_LOW_ADDRESS_LIMIT 381 359 #define ARCH_LOW_ADDRESS_LIMIT 0xffffffffUL 382 360 #endif
+12 -13
mm/sparse.c
··· 273 273 #ifdef CONFIG_MEMORY_HOTREMOVE 274 274 static unsigned long * __init 275 275 sparse_early_usemaps_alloc_pgdat_section(struct pglist_data *pgdat, 276 - unsigned long count) 276 + unsigned long size) 277 277 { 278 - unsigned long section_nr; 279 - 278 + pg_data_t *host_pgdat; 279 + unsigned long goal; 280 280 /* 281 281 * A page may contain usemaps for other sections preventing the 282 282 * page being freed and making a section unremovable while ··· 287 287 * from the same section as the pgdat where possible to avoid 288 288 * this problem. 289 289 */ 290 - section_nr = pfn_to_section_nr(__pa(pgdat) >> PAGE_SHIFT); 291 - return alloc_bootmem_section(usemap_size() * count, section_nr); 290 + goal = __pa(pgdat) & PAGE_SECTION_MASK; 291 + host_pgdat = NODE_DATA(early_pfn_to_nid(goal >> PAGE_SHIFT)); 292 + return __alloc_bootmem_node_nopanic(host_pgdat, size, 293 + SMP_CACHE_BYTES, goal); 292 294 } 293 295 294 296 static void __init check_usemap_section_nr(int nid, unsigned long *usemap) ··· 334 332 #else 335 333 static unsigned long * __init 336 334 sparse_early_usemaps_alloc_pgdat_section(struct pglist_data *pgdat, 337 - unsigned long count) 335 + unsigned long size) 338 336 { 339 - return NULL; 337 + return alloc_bootmem_node_nopanic(pgdat, size); 340 338 } 341 339 342 340 static void __init check_usemap_section_nr(int nid, unsigned long *usemap) ··· 354 352 int size = usemap_size(); 355 353 356 354 usemap = sparse_early_usemaps_alloc_pgdat_section(NODE_DATA(nodeid), 357 - usemap_count); 355 + size * usemap_count); 358 356 if (!usemap) { 359 - usemap = alloc_bootmem_node(NODE_DATA(nodeid), size * usemap_count); 360 - if (!usemap) { 361 - printk(KERN_WARNING "%s: allocation failed\n", __func__); 362 - return; 363 - } 357 + printk(KERN_WARNING "%s: allocation failed\n", __func__); 358 + return; 364 359 } 365 360 366 361 for (pnum = pnum_begin; pnum < pnum_end; pnum++) {