thp: allocate memory in khugepaged outside of mmap_sem write mode
[linux-2.6.git] / mm / mmzone.c
index febea1c..f5b7d17 100644 (file)
@@ -6,6 +6,7 @@
 
 
 #include <linux/stddef.h>
+#include <linux/mm.h>
 #include <linux/mmzone.h>
 #include <linux/module.h>
 
@@ -14,8 +15,6 @@ struct pglist_data *first_online_pgdat(void)
        return NODE_DATA(first_online_node);
 }
 
-EXPORT_UNUSED_SYMBOL(first_online_pgdat);  /*  June 2006  */
-
 struct pglist_data *next_online_pgdat(struct pglist_data *pgdat)
 {
        int nid = next_online_node(pgdat->node_id);
@@ -24,8 +23,6 @@ struct pglist_data *next_online_pgdat(struct pglist_data *pgdat)
                return NULL;
        return NODE_DATA(nid);
 }
-EXPORT_UNUSED_SYMBOL(next_online_pgdat);  /*  June 2006  */
-
 
 /*
  * next_zone - helper magic for for_each_zone()
@@ -45,5 +42,48 @@ struct zone *next_zone(struct zone *zone)
        }
        return zone;
 }
-EXPORT_UNUSED_SYMBOL(next_zone);  /*  June 2006  */
 
+static inline int zref_in_nodemask(struct zoneref *zref, nodemask_t *nodes)
+{
+#ifdef CONFIG_NUMA
+       return node_isset(zonelist_node_idx(zref), *nodes);
+#else
+       return 1;
+#endif /* CONFIG_NUMA */
+}
+
+/* Returns the next zone at or below highest_zoneidx in a zonelist */
+struct zoneref *next_zones_zonelist(struct zoneref *z,
+                                       enum zone_type highest_zoneidx,
+                                       nodemask_t *nodes,
+                                       struct zone **zone)
+{
+       /*
+        * Find the next suitable zone to use for the allocation.
+        * Only filter based on nodemask if it's set
+        */
+       if (likely(nodes == NULL))
+               while (zonelist_zone_idx(z) > highest_zoneidx)
+                       z++;
+       else
+               while (zonelist_zone_idx(z) > highest_zoneidx ||
+                               (z->zone && !zref_in_nodemask(z, nodes)))
+                       z++;
+
+       *zone = zonelist_zone(z);
+       return z;
+}
+
+#ifdef CONFIG_ARCH_HAS_HOLES_MEMORYMODEL
+int memmap_valid_within(unsigned long pfn,
+                                       struct page *page, struct zone *zone)
+{
+       if (page_to_pfn(page) != pfn)
+               return 0;
+
+       if (page_zone(page) != zone)
+               return 0;
+
+       return 1;
+}
+#endif /* CONFIG_ARCH_HAS_HOLES_MEMORYMODEL */