mm: bootmem: allocate in order node+goal, goal, node, anywhere
authorJohannes Weiner <hannes@cmpxchg.org>
Tue, 29 May 2012 22:06:34 +0000 (15:06 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 29 May 2012 23:22:21 +0000 (16:22 -0700)
Match the nobootmem version of __alloc_bootmem_node.  Try to satisfy both
the node and the goal, then just the goal, then just the node, then
allocate anywhere before panicking.

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>
mm/bootmem.c

index bafeb2c171c757b551f01030f29399d5715011b0..b5babdfb9ef838be335ef942722fc6d4c8d35ae1 100644 (file)
@@ -704,6 +704,7 @@ static void * __init ___alloc_bootmem_node(bootmem_data_t *bdata,
 {
        void *ptr;
 
+again:
        ptr = alloc_arch_preferred_bootmem(bdata, size, align, goal, limit);
        if (ptr)
                return ptr;
@@ -712,7 +713,18 @@ static void * __init ___alloc_bootmem_node(bootmem_data_t *bdata,
        if (ptr)
                return ptr;
 
-       return ___alloc_bootmem(size, align, goal, limit);
+       ptr = alloc_bootmem_core(size, align, goal, limit);
+       if (ptr)
+               return ptr;
+
+       if (goal) {
+               goal = 0;
+               goto again;
+       }
+
+       printk(KERN_ALERT "bootmem alloc of %lu bytes failed!\n", size);
+       panic("Out of memory");
+       return NULL;
 }
 
 /**