diff options
author | Linus Torvalds <torvalds@osdl.org> | 2006-02-17 14:38:21 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-02-17 16:27:06 -0500 |
commit | 4cf808eb443ead42777a0230b73aec0cee7fb298 (patch) | |
tree | 2d6dac429fcfcf18c9837c8c34164eff03e46fec /mm | |
parent | cfe91f9ce297e23e6fbdf61c02bdd8ab9af7c8a8 (diff) |
[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>
Diffstat (limited to 'mm')
-rw-r--r-- | mm/page_alloc.c | 22 |
1 files changed, 11 insertions, 11 deletions
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 62c122528587..208812b25597 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c | |||
@@ -1541,29 +1541,29 @@ static int __initdata node_load[MAX_NUMNODES]; | |||
1541 | */ | 1541 | */ |
1542 | static int __init find_next_best_node(int node, nodemask_t *used_node_mask) | 1542 | static int __init find_next_best_node(int node, nodemask_t *used_node_mask) |
1543 | { | 1543 | { |
1544 | int i, n, val; | 1544 | int n, val; |
1545 | int min_val = INT_MAX; | 1545 | int min_val = INT_MAX; |
1546 | int best_node = -1; | 1546 | int best_node = -1; |
1547 | 1547 | ||
1548 | for_each_online_node(i) { | 1548 | /* Use the local node if we haven't already */ |
1549 | cpumask_t tmp; | 1549 | if (!node_isset(node, *used_node_mask)) { |
1550 | node_set(node, *used_node_mask); | ||
1551 | return node; | ||
1552 | } | ||
1550 | 1553 | ||
1551 | /* Start from local node */ | 1554 | for_each_online_node(n) { |
1552 | n = (node+i) % num_online_nodes(); | 1555 | cpumask_t tmp; |
1553 | 1556 | ||
1554 | /* Don't want a node to appear more than once */ | 1557 | /* Don't want a node to appear more than once */ |
1555 | if (node_isset(n, *used_node_mask)) | 1558 | if (node_isset(n, *used_node_mask)) |
1556 | continue; | 1559 | continue; |
1557 | 1560 | ||
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 */ | 1561 | /* Use the distance array to find the distance */ |
1565 | val = node_distance(node, n); | 1562 | val = node_distance(node, n); |
1566 | 1563 | ||
1564 | /* Penalize nodes under us ("prefer the next node") */ | ||
1565 | val += (n < node); | ||
1566 | |||
1567 | /* Give preference to headless and unused nodes */ | 1567 | /* Give preference to headless and unused nodes */ |
1568 | tmp = node_to_cpumask(n); | 1568 | tmp = node_to_cpumask(n); |
1569 | if (!cpus_empty(tmp)) | 1569 | if (!cpus_empty(tmp)) |