aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86_64/mm/srat.c27
1 files changed, 27 insertions, 0 deletions
diff --git a/arch/x86_64/mm/srat.c b/arch/x86_64/mm/srat.c
index 33340bd1e328..9f69d28652f8 100644
--- a/arch/x86_64/mm/srat.c
+++ b/arch/x86_64/mm/srat.c
@@ -91,9 +91,36 @@ static __init inline int srat_disabled(void)
91 return numa_off || acpi_numa < 0; 91 return numa_off || acpi_numa < 0;
92} 92}
93 93
94/*
95 * A lot of BIOS fill in 10 (= no distance) everywhere. This messes
96 * up the NUMA heuristics which wants the local node to have a smaller
97 * distance than the others.
98 * Do some quick checks here and only use the SLIT if it passes.
99 */
100static __init int slit_valid(struct acpi_table_slit *slit)
101{
102 int i, j;
103 int d = slit->localities;
104 for (i = 0; i < d; i++) {
105 for (j = 0; j < d; j++) {
106 u8 val = slit->entry[d*i + j];
107 if (i == j) {
108 if (val != 10)
109 return 0;
110 } else if (val <= 10)
111 return 0;
112 }
113 }
114 return 1;
115}
116
94/* Callback for SLIT parsing */ 117/* Callback for SLIT parsing */
95void __init acpi_numa_slit_init(struct acpi_table_slit *slit) 118void __init acpi_numa_slit_init(struct acpi_table_slit *slit)
96{ 119{
120 if (!slit_valid(slit)) {
121 printk(KERN_INFO "ACPI: SLIT table looks invalid. Not used.\n");
122 return;
123 }
97 acpi_slit = slit; 124 acpi_slit = slit;
98} 125}
99 126