aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/numa.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/numa.c')
-rw-r--r--drivers/acpi/numa.c35
1 files changed, 29 insertions, 6 deletions
diff --git a/drivers/acpi/numa.c b/drivers/acpi/numa.c
index 5d59cb33b1a5..cb9864e39bae 100644
--- a/drivers/acpi/numa.c
+++ b/drivers/acpi/numa.c
@@ -120,10 +120,10 @@ acpi_table_print_srat_entry(struct acpi_subtable_header *header)
120 struct acpi_srat_mem_affinity *p = 120 struct acpi_srat_mem_affinity *p =
121 (struct acpi_srat_mem_affinity *)header; 121 (struct acpi_srat_mem_affinity *)header;
122 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 122 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
123 "SRAT Memory (0x%lx length 0x%lx type 0x%x) in proximity domain %d %s%s\n", 123 "SRAT Memory (0x%lx length 0x%lx) in proximity domain %d %s%s\n",
124 (unsigned long)p->base_address, 124 (unsigned long)p->base_address,
125 (unsigned long)p->length, 125 (unsigned long)p->length,
126 p->memory_type, p->proximity_domain, 126 p->proximity_domain,
127 (p->flags & ACPI_SRAT_MEM_ENABLED)? 127 (p->flags & ACPI_SRAT_MEM_ENABLED)?
128 "enabled" : "disabled", 128 "enabled" : "disabled",
129 (p->flags & ACPI_SRAT_MEM_HOT_PLUGGABLE)? 129 (p->flags & ACPI_SRAT_MEM_HOT_PLUGGABLE)?
@@ -140,19 +140,42 @@ acpi_table_print_srat_entry(struct acpi_subtable_header *header)
140 } 140 }
141} 141}
142 142
143/*
144 * A lot of BIOS fill in 10 (= no distance) everywhere. This messes
145 * up the NUMA heuristics which wants the local node to have a smaller
146 * distance than the others.
147 * Do some quick checks here and only use the SLIT if it passes.
148 */
149static __init int slit_valid(struct acpi_table_slit *slit)
150{
151 int i, j;
152 int d = slit->locality_count;
153 for (i = 0; i < d; i++) {
154 for (j = 0; j < d; j++) {
155 u8 val = slit->entry[d*i + j];
156 if (i == j) {
157 if (val != LOCAL_DISTANCE)
158 return 0;
159 } else if (val <= LOCAL_DISTANCE)
160 return 0;
161 }
162 }
163 return 1;
164}
165
143static int __init acpi_parse_slit(struct acpi_table_header *table) 166static int __init acpi_parse_slit(struct acpi_table_header *table)
144{ 167{
145 struct acpi_table_slit *slit; 168 struct acpi_table_slit *slit;
146 u32 localities;
147 169
148 if (!table) 170 if (!table)
149 return -EINVAL; 171 return -EINVAL;
150 172
151 slit = (struct acpi_table_slit *)table; 173 slit = (struct acpi_table_slit *)table;
152 174
153 /* downcast just for %llu vs %lu for i386/ia64 */ 175 if (!slit_valid(slit)) {
154 localities = (u32) slit->locality_count; 176 printk(KERN_INFO "ACPI: SLIT table looks invalid. Not used.\n");
155 177 return -EINVAL;
178 }
156 acpi_numa_slit_init(slit); 179 acpi_numa_slit_init(slit);
157 180
158 return 0; 181 return 0;