X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=blobdiff_plain;ds=sidebyside;f=drivers%2Facpi%2Fnuma.c;h=658e5f3abae0dda28d73395955d8e91c7126c846;hb=48cf937f48f68bd1e61f37c6357dbff5adb95532;hp=5d59cb33b1a5435ba16052b032a9f8c24da15e1a;hpb=81e242d0efafb319938d511b115088a5c4523c91;p=linux-2.6 diff --git a/drivers/acpi/numa.c b/drivers/acpi/numa.c index 5d59cb33b1..658e5f3aba 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) } } +/* + * A lot of BIOS fill in 10 (= no distance) everywhere. This messes + * up the NUMA heuristics which wants the local node to have a smaller + * distance than the others. + * Do some quick checks here and only use the SLIT if it passes. + */ +static __init int slit_valid(struct acpi_table_slit *slit) +{ + int i, j; + int d = slit->locality_count; + for (i = 0; i < d; i++) { + for (j = 0; j < d; j++) { + u8 val = slit->entry[d*i + j]; + if (i == j) { + if (val != LOCAL_DISTANCE) + return 0; + } else if (val <= LOCAL_DISTANCE) + return 0; + } + } + return 1; +} + static int __init acpi_parse_slit(struct acpi_table_header *table) { struct acpi_table_slit *slit; - u32 localities; if (!table) return -EINVAL; slit = (struct acpi_table_slit *)table; - /* downcast just for %llu vs %lu for i386/ia64 */ - localities = (u32) slit->locality_count; - + if (!slit_valid(slit)) { + printk(KERN_INFO "ACPI: SLIT table looks invalid. Not used.\n"); + return -EINVAL; + } acpi_numa_slit_init(slit); return 0;