diff options
Diffstat (limited to 'arch/x86_64')
-rw-r--r-- | arch/x86_64/mm/srat.c | 26 |
1 files changed, 20 insertions, 6 deletions
diff --git a/arch/x86_64/mm/srat.c b/arch/x86_64/mm/srat.c index 8b7f85608fa8..3bd827f5611f 100644 --- a/arch/x86_64/mm/srat.c +++ b/arch/x86_64/mm/srat.c | |||
@@ -26,6 +26,10 @@ static nodemask_t nodes_found __initdata; | |||
26 | static struct node nodes[MAX_NUMNODES] __initdata; | 26 | static struct node nodes[MAX_NUMNODES] __initdata; |
27 | static u8 pxm2node[256] = { [0 ... 255] = 0xff }; | 27 | static u8 pxm2node[256] = { [0 ... 255] = 0xff }; |
28 | 28 | ||
29 | /* Too small nodes confuse the VM badly. Usually they result | ||
30 | from BIOS bugs. */ | ||
31 | #define NODE_MIN_SIZE (4*1024*1024) | ||
32 | |||
29 | static int node_to_pxm(int n); | 33 | static int node_to_pxm(int n); |
30 | 34 | ||
31 | int pxm_to_node(int pxm) | 35 | int pxm_to_node(int pxm) |
@@ -223,6 +227,16 @@ static int nodes_cover_memory(void) | |||
223 | return 1; | 227 | return 1; |
224 | } | 228 | } |
225 | 229 | ||
230 | static void unparse_node(int node) | ||
231 | { | ||
232 | int i; | ||
233 | node_clear(node, nodes_parsed); | ||
234 | for (i = 0; i < MAX_LOCAL_APIC; i++) { | ||
235 | if (apicid_to_node[i] == node) | ||
236 | apicid_to_node[i] = NUMA_NO_NODE; | ||
237 | } | ||
238 | } | ||
239 | |||
226 | void __init acpi_numa_arch_fixup(void) {} | 240 | void __init acpi_numa_arch_fixup(void) {} |
227 | 241 | ||
228 | /* Use the information discovered above to actually set up the nodes. */ | 242 | /* Use the information discovered above to actually set up the nodes. */ |
@@ -230,16 +244,16 @@ int __init acpi_scan_nodes(unsigned long start, unsigned long end) | |||
230 | { | 244 | { |
231 | int i; | 245 | int i; |
232 | 246 | ||
233 | if (acpi_numa <= 0) | ||
234 | return -1; | ||
235 | |||
236 | /* First clean up the node list */ | 247 | /* First clean up the node list */ |
237 | for_each_node_mask(i, nodes_parsed) { | 248 | for (i = 0; i < MAX_NUMNODES; i++) { |
238 | cutoff_node(i, start, end); | 249 | cutoff_node(i, start, end); |
239 | if (nodes[i].start == nodes[i].end) | 250 | if ((nodes[i].end - nodes[i].start) < NODE_MIN_SIZE) |
240 | node_clear(i, nodes_parsed); | 251 | unparse_node(i); |
241 | } | 252 | } |
242 | 253 | ||
254 | if (acpi_numa <= 0) | ||
255 | return -1; | ||
256 | |||
243 | if (!nodes_cover_memory()) { | 257 | if (!nodes_cover_memory()) { |
244 | bad_srat(); | 258 | bad_srat(); |
245 | return -1; | 259 | return -1; |