From 58fc949e945ae63e4fe3c9d88bfe0307348030d7 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Wed, 11 Jan 2006 22:43:42 +0100 Subject: [PATCH] --- yaml --- r: 17952 b: refs/heads/master c: 1584b89c921acefe88881f08d836d80f00600a84 h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/arch/x86_64/mm/srat.c | 27 +++++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/[refs] b/[refs] index 5aa835ce976c..5db7f6738470 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 7a4a76cc1057de0dc96ee481590347aa8c5b9ffb +refs/heads/master: 1584b89c921acefe88881f08d836d80f00600a84 diff --git a/trunk/arch/x86_64/mm/srat.c b/trunk/arch/x86_64/mm/srat.c index 33340bd1e328..9f69d28652f8 100644 --- a/trunk/arch/x86_64/mm/srat.c +++ b/trunk/arch/x86_64/mm/srat.c @@ -91,9 +91,36 @@ static __init inline int srat_disabled(void) return numa_off || acpi_numa < 0; } +/* + * 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->localities; + for (i = 0; i < d; i++) { + for (j = 0; j < d; j++) { + u8 val = slit->entry[d*i + j]; + if (i == j) { + if (val != 10) + return 0; + } else if (val <= 10) + return 0; + } + } + return 1; +} + /* Callback for SLIT parsing */ void __init acpi_numa_slit_init(struct acpi_table_slit *slit) { + if (!slit_valid(slit)) { + printk(KERN_INFO "ACPI: SLIT table looks invalid. Not used.\n"); + return; + } acpi_slit = slit; }