mm: filter based on a nodemask as well as a gfp_mask
[linux-2.6.git] / mm / mmzone.c
index eb58386..486ed59 100644 (file)
@@ -42,3 +42,33 @@ struct zone *next_zone(struct zone *zone)
        return zone;
 }
 
+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;
+}