diff options
| -rw-r--r-- | arch/ia64/kernel/acpi.c | 9 | ||||
| -rw-r--r-- | arch/x86/mm/srat_64.c | 27 | ||||
| -rw-r--r-- | drivers/acpi/numa.c | 31 |
3 files changed, 34 insertions, 33 deletions
diff --git a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c index 853d1f11be00..43687cc60dfb 100644 --- a/arch/ia64/kernel/acpi.c +++ b/arch/ia64/kernel/acpi.c | |||
| @@ -465,7 +465,6 @@ void __init acpi_numa_slit_init(struct acpi_table_slit *slit) | |||
| 465 | printk(KERN_ERR | 465 | printk(KERN_ERR |
| 466 | "ACPI 2.0 SLIT: size mismatch: %d expected, %d actual\n", | 466 | "ACPI 2.0 SLIT: size mismatch: %d expected, %d actual\n", |
| 467 | len, slit->header.length); | 467 | len, slit->header.length); |
| 468 | memset(numa_slit, 10, sizeof(numa_slit)); | ||
| 469 | return; | 468 | return; |
| 470 | } | 469 | } |
| 471 | slit_table = slit; | 470 | slit_table = slit; |
| @@ -574,8 +573,14 @@ void __init acpi_numa_arch_fixup(void) | |||
| 574 | printk(KERN_INFO "Number of memory chunks in system = %d\n", | 573 | printk(KERN_INFO "Number of memory chunks in system = %d\n", |
| 575 | num_node_memblks); | 574 | num_node_memblks); |
| 576 | 575 | ||
| 577 | if (!slit_table) | 576 | if (!slit_table) { |
| 577 | for (i = 0; i < MAX_NUMNODES; i++) | ||
| 578 | for (j = 0; j < MAX_NUMNODES; j++) | ||
| 579 | node_distance(i, j) = i == j ? LOCAL_DISTANCE : | ||
| 580 | REMOTE_DISTANCE; | ||
| 578 | return; | 581 | return; |
| 582 | } | ||
| 583 | |||
| 579 | memset(numa_slit, -1, sizeof(numa_slit)); | 584 | memset(numa_slit, -1, sizeof(numa_slit)); |
| 580 | for (i = 0; i < slit_table->locality_count; i++) { | 585 | for (i = 0; i < slit_table->locality_count; i++) { |
| 581 | if (!pxm_bit_test(i)) | 586 | if (!pxm_bit_test(i)) |
diff --git a/arch/x86/mm/srat_64.c b/arch/x86/mm/srat_64.c index 3890234e5b26..99649dccad28 100644 --- a/arch/x86/mm/srat_64.c +++ b/arch/x86/mm/srat_64.c | |||
| @@ -97,36 +97,9 @@ static __init inline int srat_disabled(void) | |||
| 97 | return numa_off || acpi_numa < 0; | 97 | return numa_off || acpi_numa < 0; |
| 98 | } | 98 | } |
| 99 | 99 | ||
| 100 | /* | ||
| 101 | * A lot of BIOS fill in 10 (= no distance) everywhere. This messes | ||
| 102 | * up the NUMA heuristics which wants the local node to have a smaller | ||
| 103 | * distance than the others. | ||
| 104 | * Do some quick checks here and only use the SLIT if it passes. | ||
| 105 | */ | ||
| 106 | static __init int slit_valid(struct acpi_table_slit *slit) | ||
| 107 | { | ||
| 108 | int i, j; | ||
| 109 | int d = slit->locality_count; | ||
| 110 | for (i = 0; i < d; i++) { | ||
| 111 | for (j = 0; j < d; j++) { | ||
| 112 | u8 val = slit->entry[d*i + j]; | ||
| 113 | if (i == j) { | ||
| 114 | if (val != LOCAL_DISTANCE) | ||
| 115 | return 0; | ||
| 116 | } else if (val <= LOCAL_DISTANCE) | ||
| 117 | return 0; | ||
| 118 | } | ||
| 119 | } | ||
| 120 | return 1; | ||
| 121 | } | ||
| 122 | |||
| 123 | /* Callback for SLIT parsing */ | 100 | /* Callback for SLIT parsing */ |
| 124 | void __init acpi_numa_slit_init(struct acpi_table_slit *slit) | 101 | void __init acpi_numa_slit_init(struct acpi_table_slit *slit) |
| 125 | { | 102 | { |
| 126 | if (!slit_valid(slit)) { | ||
| 127 | printk(KERN_INFO "ACPI: SLIT table looks invalid. Not used.\n"); | ||
| 128 | return; | ||
| 129 | } | ||
| 130 | acpi_slit = slit; | 103 | acpi_slit = slit; |
| 131 | } | 104 | } |
| 132 | 105 | ||
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; |
