Commit 4e1c2b284461fd8aa8d7b295a1e911fc4390755b

Authored by David Miller
Committed by Linus Torvalds
1 parent af3a3ab296

mm: nobootmem: Correct alloc_bootmem semantics.

The comments above __alloc_bootmem_node() claim that the code will
first try the allocation using 'goal' and if that fails it will
try again but with the 'goal' requirement dropped.

Unfortunately, this is not what the code does, so fix it to do so.

This is important for nobootmem conversions to architectures such
as sparc where MAX_DMA_ADDRESS is infinity.

On such architectures all of the allocations done by generic spots,
such as the sparse-vmemmap implementation, will pass in:

	__pa(MAX_DMA_ADDRESS)

as the goal, and with the limit given as "-1" this will always fail
unless we add the appropriate fallback logic here.

Signed-off-by: David S. Miller <davem@davemloft.net>
Acked-by: Yinghai Lu <yinghai@kernel.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

Showing 1 changed file with 8 additions and 2 deletions Side-by-side Diff

... ... @@ -298,13 +298,19 @@
298 298 if (WARN_ON_ONCE(slab_is_available()))
299 299 return kzalloc_node(size, GFP_NOWAIT, pgdat->node_id);
300 300  
  301 +again:
301 302 ptr = __alloc_memory_core_early(pgdat->node_id, size, align,
302 303 goal, -1ULL);
303 304 if (ptr)
304 305 return ptr;
305 306  
306   - return __alloc_memory_core_early(MAX_NUMNODES, size, align,
307   - goal, -1ULL);
  307 + ptr = __alloc_memory_core_early(MAX_NUMNODES, size, align,
  308 + goal, -1ULL);
  309 + if (!ptr && goal) {
  310 + goal = 0;
  311 + goto again;
  312 + }
  313 + return ptr;
308 314 }
309 315  
310 316 void * __init __alloc_bootmem_node_high(pg_data_t *pgdat, unsigned long size,