Generic Virtual Memmap support for SPARSEMEM
[linux-2.6-block.git] / mm / sparse.c
index 54f3940406cba1e6bf980e273e171c856296d148..52843a76feede7b7f46b15874b7ff68dc32ca9a2 100644 (file)
@@ -9,6 +9,8 @@
 #include <linux/spinlock.h>
 #include <linux/vmalloc.h>
 #include <asm/dma.h>
+#include <asm/pgalloc.h>
+#include <asm/pgtable.h>
 
 /*
  * Permanent SPARSEMEM data:
@@ -222,11 +224,10 @@ void *alloc_bootmem_high_node(pg_data_t *pgdat, unsigned long size)
        return NULL;
 }
 
-static struct page __init *sparse_early_mem_map_alloc(unsigned long pnum)
+#ifndef CONFIG_SPARSEMEM_VMEMMAP
+struct page __init *sparse_early_mem_map_populate(unsigned long pnum, int nid)
 {
        struct page *map;
-       struct mem_section *ms = __nr_to_section(pnum);
-       int nid = sparse_early_nid(ms);
 
        map = alloc_remap(nid, sizeof(struct page) * PAGES_PER_SECTION);
        if (map)
@@ -239,10 +240,22 @@ static struct page __init *sparse_early_mem_map_alloc(unsigned long pnum)
 
        map = alloc_bootmem_node(NODE_DATA(nid),
                        sizeof(struct page) * PAGES_PER_SECTION);
+       return map;
+}
+#endif /* !CONFIG_SPARSEMEM_VMEMMAP */
+
+struct page __init *sparse_early_mem_map_alloc(unsigned long pnum)
+{
+       struct page *map;
+       struct mem_section *ms = __nr_to_section(pnum);
+       int nid = sparse_early_nid(ms);
+
+       map = sparse_early_mem_map_populate(pnum, nid);
        if (map)
                return map;
 
-       printk(KERN_WARNING "%s: allocation failed\n", __FUNCTION__);
+       printk(KERN_ERR "%s: sparsemem memory map backing failed "
+                       "some memory will not be available.\n", __FUNCTION__);
        ms->section_mem_map = 0;
        return NULL;
 }