[PATCH] mm: move determination of policy_zone into page allocator
authorChristoph Lameter <clameter@engr.sgi.com>
Fri, 6 Jan 2006 08:11:17 +0000 (00:11 -0800)
committerLinus Torvalds <torvalds@g5.osdl.org>
Fri, 6 Jan 2006 16:33:28 +0000 (08:33 -0800)
Currently the function to build a zonelist for a BIND policy has the side
effect to set the policy_zone.  This seems to be a bit strange.  policy
zone seems to not be initialized elsewhere and therefore 0.  Do we police
ZONE_DMA if no bind policy has been used yet?

This patch moves the determination of the zone to apply policies to into
the page allocator.  We determine the zone while building the zonelist for
nodes.

Signed-off-by: Christoph Lameter <clameter@sgi.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
include/linux/mempolicy.h
mm/mempolicy.c
mm/page_alloc.c

index b972f985a3c5cb5e7a5821045bf5b4719098528a..ed00b278cb9324935aa0bfb3f8a0b7484eb6e992 100644 (file)
@@ -151,6 +151,14 @@ extern struct mempolicy default_policy;
 extern struct zonelist *huge_zonelist(struct vm_area_struct *vma,
                unsigned long addr);
 
+extern int policy_zone;
+
+static inline void check_highest_zone(int k)
+{
+       if (k > policy_zone)
+               policy_zone = k;
+}
+
 #else
 
 struct mempolicy {};
@@ -221,6 +229,9 @@ static inline struct zonelist *huge_zonelist(struct vm_area_struct *vma,
        return NODE_DATA(0)->node_zonelists + gfp_zone(GFP_HIGHUSER);
 }
 
+static inline void check_highest_zone(int k)
+{
+}
 #endif /* CONFIG_NUMA */
 #endif /* __KERNEL__ */
 
index 96714e2646adae71507b67374d4724b2d6a1de05..0f1d2b8a952b900f899ea19233c84b862909323d 100644 (file)
@@ -93,7 +93,7 @@ static kmem_cache_t *sn_cache;
 
 /* Highest zone. An specific allocation for a zone below that is not
    policied. */
-static int policy_zone;
+int policy_zone = ZONE_DMA;
 
 struct mempolicy default_policy = {
        .refcnt = ATOMIC_INIT(1), /* never free it */
@@ -131,17 +131,8 @@ static struct zonelist *bind_zonelist(nodemask_t *nodes)
        if (!zl)
                return NULL;
        num = 0;
-       for_each_node_mask(nd, *nodes) {
-               int k;
-               for (k = MAX_NR_ZONES-1; k >= 0; k--) {
-                       struct zone *z = &NODE_DATA(nd)->node_zones[k];
-                       if (!z->present_pages)
-                               continue;
-                       zl->zones[num++] = z;
-                       if (k > policy_zone)
-                               policy_zone = k;
-               }
-       }
+       for_each_node_mask(nd, *nodes)
+               zl->zones[num++] = &NODE_DATA(nd)->node_zones[policy_zone];
        zl->zones[num] = NULL;
        return zl;
 }
index 7adc9526d329fb99957b091333b9f0f54ccdc2a3..512e3f4d4963ecf4e255ab74f7fdc1aa1b5ff494 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/memory_hotplug.h>
 #include <linux/nodemask.h>
 #include <linux/vmalloc.h>
+#include <linux/mempolicy.h>
 
 #include <asm/tlbflush.h>
 #include "internal.h"
@@ -1470,6 +1471,7 @@ static int __init build_zonelists_node(pg_data_t *pgdat,
                        BUG_ON(zone - pgdat->node_zones > ZONE_NORMAL);
 #endif
                        zonelist->zones[j++] = zone;
+                       check_highest_zone(k);
                }
        }
        return j;