diff options
Diffstat (limited to 'drivers/acpi/numa.c')
| -rw-r--r-- | drivers/acpi/numa.c | 31 |
1 files changed, 27 insertions, 4 deletions
diff --git a/drivers/acpi/numa.c b/drivers/acpi/numa.c index 5d59cb33b1a5..658e5f3abae0 100644 --- a/drivers/acpi/numa.c +++ b/drivers/acpi/numa.c | |||
| @@ -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 | */ | ||
| 149 | static __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 | |||
| 143 | static int __init acpi_parse_slit(struct acpi_table_header *table) | 166 | static 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; |
