diff options
Diffstat (limited to 'arch/x86_64/mm/srat.c')
-rw-r--r-- | arch/x86_64/mm/srat.c | 45 |
1 files changed, 35 insertions, 10 deletions
diff --git a/arch/x86_64/mm/srat.c b/arch/x86_64/mm/srat.c index 8b7f85608fa8..cd25300726fc 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) |
@@ -131,7 +135,12 @@ void __init | |||
131 | acpi_numa_processor_affinity_init(struct acpi_table_processor_affinity *pa) | 135 | acpi_numa_processor_affinity_init(struct acpi_table_processor_affinity *pa) |
132 | { | 136 | { |
133 | int pxm, node; | 137 | int pxm, node; |
134 | if (srat_disabled() || pa->flags.enabled == 0) | 138 | if (srat_disabled()) |
139 | return; | ||
140 | if (pa->header.length != sizeof(struct acpi_table_processor_affinity)) { bad_srat(); | ||
141 | return; | ||
142 | } | ||
143 | if (pa->flags.enabled == 0) | ||
135 | return; | 144 | return; |
136 | pxm = pa->proximity_domain; | 145 | pxm = pa->proximity_domain; |
137 | node = setup_node(pxm); | 146 | node = setup_node(pxm); |
@@ -155,8 +164,16 @@ acpi_numa_memory_affinity_init(struct acpi_table_memory_affinity *ma) | |||
155 | int node, pxm; | 164 | int node, pxm; |
156 | int i; | 165 | int i; |
157 | 166 | ||
158 | if (srat_disabled() || ma->flags.enabled == 0) | 167 | if (srat_disabled()) |
168 | return; | ||
169 | if (ma->header.length != sizeof(struct acpi_table_memory_affinity)) { | ||
170 | bad_srat(); | ||
159 | return; | 171 | return; |
172 | } | ||
173 | if (ma->flags.enabled == 0) | ||
174 | return; | ||
175 | start = ma->base_addr_lo | ((u64)ma->base_addr_hi << 32); | ||
176 | end = start + (ma->length_lo | ((u64)ma->length_hi << 32)); | ||
160 | pxm = ma->proximity_domain; | 177 | pxm = ma->proximity_domain; |
161 | node = setup_node(pxm); | 178 | node = setup_node(pxm); |
162 | if (node < 0) { | 179 | if (node < 0) { |
@@ -164,8 +181,6 @@ acpi_numa_memory_affinity_init(struct acpi_table_memory_affinity *ma) | |||
164 | bad_srat(); | 181 | bad_srat(); |
165 | return; | 182 | return; |
166 | } | 183 | } |
167 | start = ma->base_addr_lo | ((u64)ma->base_addr_hi << 32); | ||
168 | end = start + (ma->length_lo | ((u64)ma->length_hi << 32)); | ||
169 | /* It is fine to add this area to the nodes data it will be used later*/ | 184 | /* It is fine to add this area to the nodes data it will be used later*/ |
170 | if (ma->flags.hot_pluggable == 1) | 185 | if (ma->flags.hot_pluggable == 1) |
171 | printk(KERN_INFO "SRAT: hot plug zone found %lx - %lx \n", | 186 | printk(KERN_INFO "SRAT: hot plug zone found %lx - %lx \n", |
@@ -223,6 +238,16 @@ static int nodes_cover_memory(void) | |||
223 | return 1; | 238 | return 1; |
224 | } | 239 | } |
225 | 240 | ||
241 | static void unparse_node(int node) | ||
242 | { | ||
243 | int i; | ||
244 | node_clear(node, nodes_parsed); | ||
245 | for (i = 0; i < MAX_LOCAL_APIC; i++) { | ||
246 | if (apicid_to_node[i] == node) | ||
247 | apicid_to_node[i] = NUMA_NO_NODE; | ||
248 | } | ||
249 | } | ||
250 | |||
226 | void __init acpi_numa_arch_fixup(void) {} | 251 | void __init acpi_numa_arch_fixup(void) {} |
227 | 252 | ||
228 | /* Use the information discovered above to actually set up the nodes. */ | 253 | /* Use the information discovered above to actually set up the nodes. */ |
@@ -230,16 +255,16 @@ int __init acpi_scan_nodes(unsigned long start, unsigned long end) | |||
230 | { | 255 | { |
231 | int i; | 256 | int i; |
232 | 257 | ||
233 | if (acpi_numa <= 0) | ||
234 | return -1; | ||
235 | |||
236 | /* First clean up the node list */ | 258 | /* First clean up the node list */ |
237 | for_each_node_mask(i, nodes_parsed) { | 259 | for (i = 0; i < MAX_NUMNODES; i++) { |
238 | cutoff_node(i, start, end); | 260 | cutoff_node(i, start, end); |
239 | if (nodes[i].start == nodes[i].end) | 261 | if ((nodes[i].end - nodes[i].start) < NODE_MIN_SIZE) |
240 | node_clear(i, nodes_parsed); | 262 | unparse_node(i); |
241 | } | 263 | } |
242 | 264 | ||
265 | if (acpi_numa <= 0) | ||
266 | return -1; | ||
267 | |||
243 | if (!nodes_cover_memory()) { | 268 | if (!nodes_cover_memory()) { |
244 | bad_srat(); | 269 | bad_srat(); |
245 | return -1; | 270 | return -1; |