[PATCH] Handle holes in node mask in node fallback list setup

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>

authored by Linus Torvalds and committed by Linus Torvalds 4cf808eb cfe91f9c

+11 -11
+11 -11
mm/page_alloc.c
··· 1541 */ 1542 static int __init find_next_best_node(int node, nodemask_t *used_node_mask) 1543 { 1544 - int i, n, val; 1545 int min_val = INT_MAX; 1546 int best_node = -1; 1547 1548 - for_each_online_node(i) { 1549 - cpumask_t tmp; 1550 1551 - /* Start from local node */ 1552 - n = (node+i) % num_online_nodes(); 1553 1554 /* Don't want a node to appear more than once */ 1555 if (node_isset(n, *used_node_mask)) 1556 continue; 1557 1558 - /* Use the local node if we haven't already */ 1559 - if (!node_isset(node, *used_node_mask)) { 1560 - best_node = node; 1561 - break; 1562 - } 1563 - 1564 /* Use the distance array to find the distance */ 1565 val = node_distance(node, n); 1566 1567 /* Give preference to headless and unused nodes */ 1568 tmp = node_to_cpumask(n);
··· 1541 */ 1542 static int __init find_next_best_node(int node, nodemask_t *used_node_mask) 1543 { 1544 + int n, val; 1545 int min_val = INT_MAX; 1546 int best_node = -1; 1547 1548 + /* Use the local node if we haven't already */ 1549 + if (!node_isset(node, *used_node_mask)) { 1550 + node_set(node, *used_node_mask); 1551 + return node; 1552 + } 1553 1554 + for_each_online_node(n) { 1555 + cpumask_t tmp; 1556 1557 /* Don't want a node to appear more than once */ 1558 if (node_isset(n, *used_node_mask)) 1559 continue; 1560 1561 /* Use the distance array to find the distance */ 1562 val = node_distance(node, n); 1563 + 1564 + /* Penalize nodes under us ("prefer the next node") */ 1565 + val += (n < node); 1566 1567 /* Give preference to headless and unused nodes */ 1568 tmp = node_to_cpumask(n);