memblock: NUMA allocate can now use early_pfn_map
[linux-3.10.git] / mm / memblock.c
index 468ff43..af7e4d9 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/init.h>
 #include <linux/bitops.h>
 #include <linux/poison.h>
+#include <linux/pfn.h>
 #include <linux/memblock.h>
 
 struct memblock memblock;
@@ -451,11 +452,36 @@ phys_addr_t __init memblock_alloc(phys_addr_t size, phys_addr_t align)
 /*
  * Additional node-local allocators. Search for node memory is bottom up
  * and walks memblock regions within that node bottom-up as well, but allocation
- * within an memblock region is top-down.
+ * within an memblock region is top-down. XXX I plan to fix that at some stage
+ *
+ * WARNING: Only available after early_node_map[] has been populated,
+ * on some architectures, that is after all the calls to add_active_range()
+ * have been done to populate it.
  */
 
 phys_addr_t __weak __init memblock_nid_range(phys_addr_t start, phys_addr_t end, int *nid)
 {
+#ifdef CONFIG_ARCH_POPULATES_NODE_MAP
+       /*
+        * This code originates from sparc which really wants use to walk by addresses
+        * and returns the nid. This is not very convenient for early_pfn_map[] users
+        * as the map isn't sorted yet, and it really wants to be walked by nid.
+        *
+        * For now, I implement the inefficient method below which walks the early
+        * map multiple times. Eventually we may want to use an ARCH config option
+        * to implement a completely different method for both case.
+        */
+       unsigned long start_pfn, end_pfn;
+       int i;
+
+       for (i = 0; i < MAX_NUMNODES; i++) {
+               get_pfn_range_for_nid(i, &start_pfn, &end_pfn);
+               if (start < PFN_PHYS(start_pfn) || start >= PFN_PHYS(end_pfn))
+                       continue;
+               *nid = i;
+               return min(end, PFN_PHYS(end_pfn));
+       }
+#endif
        *nid = 0;
 
        return end;