forked from mirrors/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>
This commit is contained in:
		
							parent
							
								
									e9079911e6
								
							
						
					
					
						commit
						238305bb4d
					
				
					 4 changed files with 12 additions and 60 deletions
				
			
		|  | @ -135,9 +135,6 @@ extern void *__alloc_bootmem_low_node(pg_data_t *pgdat, | ||||||
| extern int reserve_bootmem_generic(unsigned long addr, unsigned long size, | extern int reserve_bootmem_generic(unsigned long addr, unsigned long size, | ||||||
| 				   int flags); | 				   int flags); | ||||||
| 
 | 
 | ||||||
| extern void *alloc_bootmem_section(unsigned long size, |  | ||||||
| 				   unsigned long section_nr); |  | ||||||
| 
 |  | ||||||
| #ifdef CONFIG_HAVE_ARCH_ALLOC_REMAP | #ifdef CONFIG_HAVE_ARCH_ALLOC_REMAP | ||||||
| extern void *alloc_remap(int nid, unsigned long size); | extern void *alloc_remap(int nid, unsigned long size); | ||||||
| #else | #else | ||||||
|  |  | ||||||
							
								
								
									
										22
									
								
								mm/bootmem.c
									
									
									
									
									
								
							
							
						
						
									
										22
									
								
								mm/bootmem.c
									
									
									
									
									
								
							|  | @ -803,28 +803,6 @@ void * __init __alloc_bootmem_node_high(pg_data_t *pgdat, unsigned long size, | ||||||
| 
 | 
 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #ifdef CONFIG_SPARSEMEM |  | ||||||
| /**
 |  | ||||||
|  * alloc_bootmem_section - allocate boot memory from a specific section |  | ||||||
|  * @size: size of the request in bytes |  | ||||||
|  * @section_nr: sparse map section to allocate from |  | ||||||
|  * |  | ||||||
|  * Return NULL on failure. |  | ||||||
|  */ |  | ||||||
| void * __init alloc_bootmem_section(unsigned long size, |  | ||||||
| 				    unsigned long section_nr) |  | ||||||
| { |  | ||||||
| 	bootmem_data_t *bdata; |  | ||||||
| 	unsigned long pfn, goal; |  | ||||||
| 
 |  | ||||||
| 	pfn = section_nr_to_pfn(section_nr); |  | ||||||
| 	goal = pfn << PAGE_SHIFT; |  | ||||||
| 	bdata = &bootmem_node_data[early_pfn_to_nid(pfn)]; |  | ||||||
| 
 |  | ||||||
| 	return alloc_bootmem_bdata(bdata, size, SMP_CACHE_BYTES, goal, 0); |  | ||||||
| } |  | ||||||
| #endif |  | ||||||
| 
 |  | ||||||
| #ifndef ARCH_LOW_ADDRESS_LIMIT | #ifndef ARCH_LOW_ADDRESS_LIMIT | ||||||
| #define ARCH_LOW_ADDRESS_LIMIT	0xffffffffUL | #define ARCH_LOW_ADDRESS_LIMIT	0xffffffffUL | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|  | @ -355,28 +355,6 @@ void * __init __alloc_bootmem_node_high(pg_data_t *pgdat, unsigned long size, | ||||||
| 	return __alloc_bootmem_node(pgdat, size, align, goal); | 	return __alloc_bootmem_node(pgdat, size, align, goal); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #ifdef CONFIG_SPARSEMEM |  | ||||||
| /**
 |  | ||||||
|  * alloc_bootmem_section - allocate boot memory from a specific section |  | ||||||
|  * @size: size of the request in bytes |  | ||||||
|  * @section_nr: sparse map section to allocate from |  | ||||||
|  * |  | ||||||
|  * Return NULL on failure. |  | ||||||
|  */ |  | ||||||
| void * __init alloc_bootmem_section(unsigned long size, |  | ||||||
| 				    unsigned long section_nr) |  | ||||||
| { |  | ||||||
| 	unsigned long pfn, goal, limit; |  | ||||||
| 
 |  | ||||||
| 	pfn = section_nr_to_pfn(section_nr); |  | ||||||
| 	goal = pfn << PAGE_SHIFT; |  | ||||||
| 	limit = section_nr_to_pfn(section_nr + 1) << PAGE_SHIFT; |  | ||||||
| 
 |  | ||||||
| 	return __alloc_memory_core_early(early_pfn_to_nid(pfn), size, |  | ||||||
| 					 SMP_CACHE_BYTES, goal, limit); |  | ||||||
| } |  | ||||||
| #endif |  | ||||||
| 
 |  | ||||||
| #ifndef ARCH_LOW_ADDRESS_LIMIT | #ifndef ARCH_LOW_ADDRESS_LIMIT | ||||||
| #define ARCH_LOW_ADDRESS_LIMIT	0xffffffffUL | #define ARCH_LOW_ADDRESS_LIMIT	0xffffffffUL | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
							
								
								
									
										21
									
								
								mm/sparse.c
									
									
									
									
									
								
							
							
						
						
									
										21
									
								
								mm/sparse.c
									
									
									
									
									
								
							|  | @ -273,10 +273,10 @@ static unsigned long *__kmalloc_section_usemap(void) | ||||||
| #ifdef CONFIG_MEMORY_HOTREMOVE | #ifdef CONFIG_MEMORY_HOTREMOVE | ||||||
| static unsigned long * __init | static unsigned long * __init | ||||||
| sparse_early_usemaps_alloc_pgdat_section(struct pglist_data *pgdat, | sparse_early_usemaps_alloc_pgdat_section(struct pglist_data *pgdat, | ||||||
| 					 unsigned long count) | 					 unsigned long size) | ||||||
| { | { | ||||||
| 	unsigned long section_nr; | 	pg_data_t *host_pgdat; | ||||||
| 
 | 	unsigned long goal; | ||||||
| 	/*
 | 	/*
 | ||||||
| 	 * A page may contain usemaps for other sections preventing the | 	 * A page may contain usemaps for other sections preventing the | ||||||
| 	 * page being freed and making a section unremovable while | 	 * page being freed and making a section unremovable while | ||||||
|  | @ -287,8 +287,10 @@ sparse_early_usemaps_alloc_pgdat_section(struct pglist_data *pgdat, | ||||||
| 	 * from the same section as the pgdat where possible to avoid | 	 * from the same section as the pgdat where possible to avoid | ||||||
| 	 * this problem. | 	 * this problem. | ||||||
| 	 */ | 	 */ | ||||||
| 	section_nr = pfn_to_section_nr(__pa(pgdat) >> PAGE_SHIFT); | 	goal = __pa(pgdat) & PAGE_SECTION_MASK; | ||||||
| 	return alloc_bootmem_section(usemap_size() * count, section_nr); | 	host_pgdat = NODE_DATA(early_pfn_to_nid(goal >> PAGE_SHIFT)); | ||||||
|  | 	return __alloc_bootmem_node_nopanic(host_pgdat, size, | ||||||
|  | 					    SMP_CACHE_BYTES, goal); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void __init check_usemap_section_nr(int nid, unsigned long *usemap) | static void __init check_usemap_section_nr(int nid, unsigned long *usemap) | ||||||
|  | @ -332,9 +334,9 @@ static void __init check_usemap_section_nr(int nid, unsigned long *usemap) | ||||||
| #else | #else | ||||||
| static unsigned long * __init | static unsigned long * __init | ||||||
| sparse_early_usemaps_alloc_pgdat_section(struct pglist_data *pgdat, | sparse_early_usemaps_alloc_pgdat_section(struct pglist_data *pgdat, | ||||||
| 					 unsigned long count) | 					 unsigned long size) | ||||||
| { | { | ||||||
| 	return NULL; | 	return alloc_bootmem_node_nopanic(pgdat, size); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void __init check_usemap_section_nr(int nid, unsigned long *usemap) | static void __init check_usemap_section_nr(int nid, unsigned long *usemap) | ||||||
|  | @ -352,14 +354,11 @@ static void __init sparse_early_usemaps_alloc_node(unsigned long**usemap_map, | ||||||
| 	int size = usemap_size(); | 	int size = usemap_size(); | ||||||
| 
 | 
 | ||||||
| 	usemap = sparse_early_usemaps_alloc_pgdat_section(NODE_DATA(nodeid), | 	usemap = sparse_early_usemaps_alloc_pgdat_section(NODE_DATA(nodeid), | ||||||
| 								 usemap_count); | 							  size * usemap_count); | ||||||
| 	if (!usemap) { |  | ||||||
| 		usemap = alloc_bootmem_node(NODE_DATA(nodeid), size * usemap_count); |  | ||||||
| 	if (!usemap) { | 	if (!usemap) { | ||||||
| 		printk(KERN_WARNING "%s: allocation failed\n", __func__); | 		printk(KERN_WARNING "%s: allocation failed\n", __func__); | ||||||
| 		return; | 		return; | ||||||
| 	} | 	} | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	for (pnum = pnum_begin; pnum < pnum_end; pnum++) { | 	for (pnum = pnum_begin; pnum < pnum_end; pnum++) { | ||||||
| 		if (!present_section_nr(pnum)) | 		if (!present_section_nr(pnum)) | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Johannes Weiner
						Johannes Weiner