*
  * Add all populated zones of a node to the zonelist.
  */
-static int build_zonelists_node(pg_data_t *pgdat, struct zonelist *zonelist,
-                               int nr_zones)
+static int build_zonerefs_node(pg_data_t *pgdat, struct zoneref *zonerefs)
 {
        struct zone *zone;
        enum zone_type zone_type = MAX_NR_ZONES;
+       int nr_zones = 0;
 
        do {
                zone_type--;
                zone = pgdat->node_zones + zone_type;
                if (managed_zone(zone)) {
-                       zoneref_set_zone(zone,
-                               &zonelist->_zonerefs[nr_zones++]);
+                       zoneref_set_zone(zone, &zonerefs[nr_zones++]);
                        check_highest_zone(zone_type);
                }
        } while (zone_type);
  * This results in maximum locality--normal zone overflows into local
  * DMA zone, if any--but risks exhausting DMA zone.
  */
-static void build_zonelists_in_node_order(pg_data_t *pgdat, int node)
+static void build_zonelists_in_node_order(pg_data_t *pgdat, int *node_order,
+               unsigned nr_nodes)
 {
-       int j;
-       struct zonelist *zonelist;
+       struct zoneref *zonerefs;
+       int i;
+
+       zonerefs = pgdat->node_zonelists[ZONELIST_FALLBACK]._zonerefs;
+
+       for (i = 0; i < nr_nodes; i++) {
+               int nr_zones;
 
-       zonelist = &pgdat->node_zonelists[ZONELIST_FALLBACK];
-       for (j = 0; zonelist->_zonerefs[j].zone != NULL; j++)
-               ;
-       j = build_zonelists_node(NODE_DATA(node), zonelist, j);
-       zonelist->_zonerefs[j].zone = NULL;
-       zonelist->_zonerefs[j].zone_idx = 0;
+               pg_data_t *node = NODE_DATA(node_order[i]);
+
+               nr_zones = build_zonerefs_node(node, zonerefs);
+               zonerefs += nr_zones;
+       }
+       zonerefs->zone = NULL;
+       zonerefs->zone_idx = 0;
 }
 
 /*
  */
 static void build_thisnode_zonelists(pg_data_t *pgdat)
 {
-       int j;
-       struct zonelist *zonelist;
+       struct zoneref *zonerefs;
+       int nr_zones;
 
-       zonelist = &pgdat->node_zonelists[ZONELIST_NOFALLBACK];
-       j = build_zonelists_node(pgdat, zonelist, 0);
-       zonelist->_zonerefs[j].zone = NULL;
-       zonelist->_zonerefs[j].zone_idx = 0;
+       zonerefs = pgdat->node_zonelists[ZONELIST_NOFALLBACK]._zonerefs;
+       nr_zones = build_zonerefs_node(pgdat, zonerefs);
+       zonerefs += nr_zones;
+       zonerefs->zone = NULL;
+       zonerefs->zone_idx = 0;
 }
 
 /*
  * exhausted, but results in overflowing to remote node while memory
  * may still exist in local DMA zone.
  */
-static int node_order[MAX_NUMNODES];
 
 static void build_zonelists(pg_data_t *pgdat)
 {
-       int i, node, load;
+       static int node_order[MAX_NUMNODES];
+       int node, load, nr_nodes = 0;
        nodemask_t used_mask;
        int local_node, prev_node;
-       struct zonelist *zonelist;
-
-       /* initialize zonelists */
-       for (i = 0; i < MAX_ZONELISTS; i++) {
-               zonelist = pgdat->node_zonelists + i;
-               zonelist->_zonerefs[0].zone = NULL;
-               zonelist->_zonerefs[0].zone_idx = 0;
-       }
 
        /* NUMA-aware ordering of nodes */
        local_node = pgdat->node_id;
        nodes_clear(used_mask);
 
        memset(node_order, 0, sizeof(node_order));
-       i = 0;
-
        while ((node = find_next_best_node(local_node, &used_mask)) >= 0) {
                /*
                 * We don't want to pressure a particular node.
                    node_distance(local_node, prev_node))
                        node_load[node] = load;
 
+               node_order[nr_nodes++] = node;
                prev_node = node;
                load--;
-               build_zonelists_in_node_order(pgdat, node);
        }
 
+       build_zonelists_in_node_order(pgdat, node_order, nr_nodes);
        build_thisnode_zonelists(pgdat);
 }
 
 static void build_zonelists(pg_data_t *pgdat)
 {
        int node, local_node;
-       enum zone_type j;
-       struct zonelist *zonelist;
+       struct zoneref *zonerefs;
+       int nr_zones;
 
        local_node = pgdat->node_id;
 
-       zonelist = &pgdat->node_zonelists[ZONELIST_FALLBACK];
-       j = build_zonelists_node(pgdat, zonelist, 0);
+       zonerefs = pgdat->node_zonelists[ZONELIST_FALLBACK]._zonerefs;
+       nr_zones = build_zonerefs_node(pgdat, zonerefs);
+       zonerefs += nr_zones;
 
        /*
         * Now we build the zonelist so that it contains the zones
        for (node = local_node + 1; node < MAX_NUMNODES; node++) {
                if (!node_online(node))
                        continue;
-               j = build_zonelists_node(NODE_DATA(node), zonelist, j);
+               nr_zones = build_zonerefs_node(NODE_DATA(node), zonerefs);
+               zonerefs += nr_zones;
        }
        for (node = 0; node < local_node; node++) {
                if (!node_online(node))
                        continue;
-               j = build_zonelists_node(NODE_DATA(node), zonelist, j);
+               nr_zones = build_zonerefs_node(NODE_DATA(node), zonerefs);
+               zonerefs += nr_zones;
        }
 
-       zonelist->_zonerefs[j].zone = NULL;
-       zonelist->_zonerefs[j].zone_idx = 0;
+       zonerefs->zone = NULL;
+       zonerefs->zone_idx = 0;
 }
 
 #endif /* CONFIG_NUMA */