aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86_64/mm/srat.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86_64/mm/srat.c')
-rw-r--r--arch/x86_64/mm/srat.c45
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;
26static struct node nodes[MAX_NUMNODES] __initdata; 26static struct node nodes[MAX_NUMNODES] __initdata;
27static u8 pxm2node[256] = { [0 ... 255] = 0xff }; 27static 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
29static int node_to_pxm(int n); 33static int node_to_pxm(int n);
30 34
31int pxm_to_node(int pxm) 35int pxm_to_node(int pxm)
@@ -131,7 +135,12 @@ void __init
131acpi_numa_processor_affinity_init(struct acpi_table_processor_affinity *pa) 135acpi_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
241static 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
226void __init acpi_numa_arch_fixup(void) {} 251void __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;