[PATCH] Handle holes in node mask in node fallback list setup
authorLinus Torvalds <torvalds@osdl.org>
Fri, 17 Feb 2006 19:38:21 +0000 (20:38 +0100)
committerLinus Torvalds <torvalds@g5.osdl.org>
Fri, 17 Feb 2006 21:27:06 +0000 (13:27 -0800)
Change the find_next_best_node algorithm to correctly skip
over holes in the node online mask. Previously it would not handle
missing nodes correctly and cause crashes at boot.

[Written by Linus, tested by AK]

Signed-off-by: Andi Kleen <ak@suse.de>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
mm/page_alloc.c

index 62c122528587d47063b7185917c9b61d27e6383e..208812b25597b9c49b3e9f1461c44d3620b57a2a 100644 (file)
@@ -1541,29 +1541,29 @@ static int __initdata node_load[MAX_NUMNODES];
  */
 static int __init find_next_best_node(int node, nodemask_t *used_node_mask)
 {
-       int i, n, val;
+       int n, val;
        int min_val = INT_MAX;
        int best_node = -1;
 
-       for_each_online_node(i) {
-               cpumask_t tmp;
+       /* Use the local node if we haven't already */
+       if (!node_isset(node, *used_node_mask)) {
+               node_set(node, *used_node_mask);
+               return node;
+       }
 
-               /* Start from local node */
-               n = (node+i) % num_online_nodes();
+       for_each_online_node(n) {
+               cpumask_t tmp;
 
                /* Don't want a node to appear more than once */
                if (node_isset(n, *used_node_mask))
                        continue;
 
-               /* Use the local node if we haven't already */
-               if (!node_isset(node, *used_node_mask)) {
-                       best_node = node;
-                       break;
-               }
-
                /* Use the distance array to find the distance */
                val = node_distance(node, n);
 
+               /* Penalize nodes under us ("prefer the next node") */
+               val += (n < node);
+
                /* Give preference to headless and unused nodes */
                tmp = node_to_cpumask(n);
                if (!cpus_empty(tmp))