Commit 1c6e55032e24ff79668581a0f296c278ef7edd4e
Committed by
Ingo Molnar
1 parent
0699eae140
Exists in
master
and in
4 other branches
x86: use acpi_numa_init to parse on 32-bit numa
seperate SRAT finding and parsing from get_memcfg_from_srat, and let getmemcfg_from_srat only handle array from previous step. Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Showing 4 changed files with 75 additions and 173 deletions Side-by-side Diff
arch/x86/kernel/setup_32.c
... | ... | @@ -59,6 +59,7 @@ |
59 | 59 | #include <asm/setup.h> |
60 | 60 | #include <asm/arch_hooks.h> |
61 | 61 | #include <asm/sections.h> |
62 | +#include <asm/dmi.h> | |
62 | 63 | #include <asm/io_apic.h> |
63 | 64 | #include <asm/ist.h> |
64 | 65 | #include <asm/io.h> |
... | ... | @@ -185,6 +186,12 @@ |
185 | 186 | static unsigned int highmem_pages = -1; |
186 | 187 | |
187 | 188 | /* |
189 | + * Early DMI memory | |
190 | + */ | |
191 | +int dmi_alloc_index; | |
192 | +char dmi_alloc_data[DMI_MAX_DATA]; | |
193 | + | |
194 | +/* | |
188 | 195 | * Setup options |
189 | 196 | */ |
190 | 197 | struct screen_info screen_info; |
... | ... | @@ -775,6 +782,24 @@ |
775 | 782 | max_pfn = e820_end_of_ram(); |
776 | 783 | } |
777 | 784 | |
785 | + dmi_scan_machine(); | |
786 | + | |
787 | + io_delay_init(); | |
788 | + | |
789 | +#ifdef CONFIG_ACPI | |
790 | + /* | |
791 | + * Parse the ACPI tables for possible boot-time SMP configuration. | |
792 | + */ | |
793 | + acpi_boot_table_init(); | |
794 | +#endif | |
795 | + | |
796 | +#ifdef CONFIG_ACPI_NUMA | |
797 | + /* | |
798 | + * Parse SRAT to discover nodes. | |
799 | + */ | |
800 | + acpi_numa_init(); | |
801 | +#endif | |
802 | + | |
778 | 803 | max_low_pfn = setup_memory(); |
779 | 804 | |
780 | 805 | #ifdef CONFIG_ACPI_SLEEP |
... | ... | @@ -841,10 +866,6 @@ |
841 | 866 | |
842 | 867 | paravirt_post_allocator_init(); |
843 | 868 | |
844 | - dmi_scan_machine(); | |
845 | - | |
846 | - io_delay_init(); | |
847 | - | |
848 | 869 | #ifdef CONFIG_X86_SMP |
849 | 870 | /* |
850 | 871 | * setup to use the early static init tables during kernel startup |
... | ... | @@ -859,13 +880,6 @@ |
859 | 880 | |
860 | 881 | #ifdef CONFIG_X86_GENERICARCH |
861 | 882 | generic_apic_probe(); |
862 | -#endif | |
863 | - | |
864 | -#ifdef CONFIG_ACPI | |
865 | - /* | |
866 | - * Parse the ACPI tables for possible boot-time SMP configuration. | |
867 | - */ | |
868 | - acpi_boot_table_init(); | |
869 | 883 | #endif |
870 | 884 | |
871 | 885 | early_quirks(); |
arch/x86/kernel/srat_32.c
... | ... | @@ -42,7 +42,7 @@ |
42 | 42 | #define BMAP_TEST(bmap, bit) ((bmap)[NODE_ARRAY_INDEX(bit)] & (1 << NODE_ARRAY_OFFSET(bit))) |
43 | 43 | /* bitmap length; _PXM is at most 255 */ |
44 | 44 | #define PXM_BITMAP_LEN (MAX_PXM_DOMAINS / 8) |
45 | -static u8 pxm_bitmap[PXM_BITMAP_LEN]; /* bitmap of proximity domains */ | |
45 | +static u8 __initdata pxm_bitmap[PXM_BITMAP_LEN]; /* bitmap of proximity domains */ | |
46 | 46 | |
47 | 47 | #define MAX_CHUNKS_PER_NODE 3 |
48 | 48 | #define MAXCHUNKS (MAX_CHUNKS_PER_NODE * MAX_NUMNODES) |
49 | 49 | |
50 | 50 | |
51 | 51 | |
52 | 52 | |
... | ... | @@ -53,16 +53,37 @@ |
53 | 53 | u8 nid; // which cnode contains this chunk? |
54 | 54 | u8 bank; // which mem bank on this node |
55 | 55 | }; |
56 | -static struct node_memory_chunk_s node_memory_chunk[MAXCHUNKS]; | |
56 | +static struct node_memory_chunk_s __initdata node_memory_chunk[MAXCHUNKS]; | |
57 | 57 | |
58 | -static int num_memory_chunks; /* total number of memory chunks */ | |
58 | +static int __initdata num_memory_chunks; /* total number of memory chunks */ | |
59 | 59 | static u8 __initdata apicid_to_pxm[MAX_APICID]; |
60 | 60 | |
61 | +int numa_off __initdata; | |
62 | +int acpi_numa __initdata; | |
63 | + | |
64 | +static __init void bad_srat(void) | |
65 | +{ | |
66 | + printk(KERN_ERR "SRAT: SRAT not used.\n"); | |
67 | + acpi_numa = -1; | |
68 | + num_memory_chunks = 0; | |
69 | +} | |
70 | + | |
71 | +static __init inline int srat_disabled(void) | |
72 | +{ | |
73 | + return numa_off || acpi_numa < 0; | |
74 | +} | |
75 | + | |
61 | 76 | /* Identify CPU proximity domains */ |
62 | -static void __init parse_cpu_affinity_structure(char *p) | |
77 | +void __init | |
78 | +acpi_numa_processor_affinity_init(struct acpi_srat_cpu_affinity *cpu_affinity) | |
63 | 79 | { |
64 | - struct acpi_srat_cpu_affinity *cpu_affinity = | |
65 | - (struct acpi_srat_cpu_affinity *) p; | |
80 | + if (srat_disabled()) | |
81 | + return; | |
82 | + if (cpu_affinity->header.length != | |
83 | + sizeof(struct acpi_srat_cpu_affinity)) { | |
84 | + bad_srat(); | |
85 | + return; | |
86 | + } | |
66 | 87 | |
67 | 88 | if ((cpu_affinity->flags & ACPI_SRAT_CPU_ENABLED) == 0) |
68 | 89 | return; /* empty entry */ |
69 | 90 | |
70 | 91 | |
... | ... | @@ -80,15 +101,22 @@ |
80 | 101 | * Identify memory proximity domains and hot-remove capabilities. |
81 | 102 | * Fill node memory chunk list structure. |
82 | 103 | */ |
83 | -static void __init parse_memory_affinity_structure (char *sratp) | |
104 | +void __init | |
105 | +acpi_numa_memory_affinity_init(struct acpi_srat_mem_affinity *memory_affinity) | |
84 | 106 | { |
85 | 107 | unsigned long long paddr, size; |
86 | 108 | unsigned long start_pfn, end_pfn; |
87 | 109 | u8 pxm; |
88 | 110 | struct node_memory_chunk_s *p, *q, *pend; |
89 | - struct acpi_srat_mem_affinity *memory_affinity = | |
90 | - (struct acpi_srat_mem_affinity *) sratp; | |
91 | 111 | |
112 | + if (srat_disabled()) | |
113 | + return; | |
114 | + if (memory_affinity->header.length != | |
115 | + sizeof(struct acpi_srat_mem_affinity)) { | |
116 | + bad_srat(); | |
117 | + return; | |
118 | + } | |
119 | + | |
92 | 120 | if ((memory_affinity->flags & ACPI_SRAT_MEM_ENABLED) == 0) |
93 | 121 | return; /* empty entry */ |
94 | 122 | |
... | ... | @@ -135,6 +163,14 @@ |
135 | 163 | "enabled and removable" : "enabled" ) ); |
136 | 164 | } |
137 | 165 | |
166 | +/* Callback for SLIT parsing */ | |
167 | +void __init acpi_numa_slit_init(struct acpi_table_slit *slit) | |
168 | +{ | |
169 | +} | |
170 | + | |
171 | +void acpi_numa_arch_fixup(void) | |
172 | +{ | |
173 | +} | |
138 | 174 | /* |
139 | 175 | * The SRAT table always lists ascending addresses, so can always |
140 | 176 | * assume that the first "start" address that you see is the real |
141 | 177 | |
142 | 178 | |
143 | 179 | |
144 | 180 | |
... | ... | @@ -167,40 +203,14 @@ |
167 | 203 | node_end_pfn[nid] = memory_chunk->end_pfn; |
168 | 204 | } |
169 | 205 | |
170 | -/* Parse the ACPI Static Resource Affinity Table */ | |
171 | -static int __init acpi20_parse_srat(struct acpi_table_srat *sratp) | |
206 | +int __init get_memcfg_from_srat(void) | |
172 | 207 | { |
173 | - u8 *start, *end, *p; | |
174 | 208 | int i, j, nid; |
175 | 209 | |
176 | - start = (u8 *)(&(sratp->reserved) + 1); /* skip header */ | |
177 | - p = start; | |
178 | - end = (u8 *)sratp + sratp->header.length; | |
179 | 210 | |
180 | - memset(pxm_bitmap, 0, sizeof(pxm_bitmap)); /* init proximity domain bitmap */ | |
181 | - memset(node_memory_chunk, 0, sizeof(node_memory_chunk)); | |
211 | + if (srat_disabled()) | |
212 | + goto out_fail; | |
182 | 213 | |
183 | - num_memory_chunks = 0; | |
184 | - while (p < end) { | |
185 | - switch (*p) { | |
186 | - case ACPI_SRAT_TYPE_CPU_AFFINITY: | |
187 | - parse_cpu_affinity_structure(p); | |
188 | - break; | |
189 | - case ACPI_SRAT_TYPE_MEMORY_AFFINITY: | |
190 | - parse_memory_affinity_structure(p); | |
191 | - break; | |
192 | - default: | |
193 | - printk("ACPI 2.0 SRAT: unknown entry skipped: type=0x%02X, len=%d\n", p[0], p[1]); | |
194 | - break; | |
195 | - } | |
196 | - p += p[1]; | |
197 | - if (p[1] == 0) { | |
198 | - printk("acpi20_parse_srat: Entry length value is zero;" | |
199 | - " can't parse any further!\n"); | |
200 | - break; | |
201 | - } | |
202 | - } | |
203 | - | |
204 | 214 | if (num_memory_chunks == 0) { |
205 | 215 | printk("could not finy any ACPI SRAT memory areas.\n"); |
206 | 216 | goto out_fail; |
... | ... | @@ -248,7 +258,7 @@ |
248 | 258 | e820_register_active_regions(chunk->nid, chunk->start_pfn, |
249 | 259 | min(chunk->end_pfn, max_pfn)); |
250 | 260 | } |
251 | - | |
261 | + | |
252 | 262 | for_each_online_node(nid) { |
253 | 263 | unsigned long start = node_start_pfn[nid]; |
254 | 264 | unsigned long end = min(node_end_pfn[nid], max_pfn); |
... | ... | @@ -258,118 +268,6 @@ |
258 | 268 | } |
259 | 269 | return 1; |
260 | 270 | out_fail: |
261 | - return 0; | |
262 | -} | |
263 | - | |
264 | -struct acpi_static_rsdt { | |
265 | - struct acpi_table_rsdt table; | |
266 | - u32 padding[32]; /* Allow for 32 more table entries */ | |
267 | -}; | |
268 | - | |
269 | -int __init get_memcfg_from_srat(void) | |
270 | -{ | |
271 | - struct acpi_table_header *header = NULL; | |
272 | - struct acpi_table_rsdp *rsdp = NULL; | |
273 | - struct acpi_table_rsdt *rsdt = NULL; | |
274 | - acpi_native_uint rsdp_address = 0; | |
275 | - struct acpi_static_rsdt saved_rsdt; | |
276 | - int tables = 0; | |
277 | - int i = 0; | |
278 | - | |
279 | - rsdp_address = acpi_os_get_root_pointer(); | |
280 | - if (!rsdp_address) { | |
281 | - printk("%s: System description tables not found\n", | |
282 | - __func__); | |
283 | - goto out_err; | |
284 | - } | |
285 | - | |
286 | - printk("%s: assigning address to rsdp\n", __func__); | |
287 | - rsdp = (struct acpi_table_rsdp *)(u32)rsdp_address; | |
288 | - if (!rsdp) { | |
289 | - printk("%s: Didn't find ACPI root!\n", __func__); | |
290 | - goto out_err; | |
291 | - } | |
292 | - | |
293 | - printk(KERN_INFO "%.8s v%d [%.6s]\n", rsdp->signature, rsdp->revision, | |
294 | - rsdp->oem_id); | |
295 | - | |
296 | - if (strncmp(rsdp->signature, ACPI_SIG_RSDP,strlen(ACPI_SIG_RSDP))) { | |
297 | - printk(KERN_WARNING "%s: RSDP table signature incorrect\n", __func__); | |
298 | - goto out_err; | |
299 | - } | |
300 | - | |
301 | - rsdt = (struct acpi_table_rsdt *) | |
302 | - early_ioremap(rsdp->rsdt_physical_address, sizeof(saved_rsdt)); | |
303 | - | |
304 | - if (!rsdt) { | |
305 | - printk(KERN_WARNING | |
306 | - "%s: ACPI: Invalid root system description tables (RSDT)\n", | |
307 | - __func__); | |
308 | - goto out_err; | |
309 | - } | |
310 | - | |
311 | - header = &rsdt->header; | |
312 | - | |
313 | - if (strncmp(header->signature, ACPI_SIG_RSDT, strlen(ACPI_SIG_RSDT))) { | |
314 | - printk(KERN_WARNING "ACPI: RSDT signature incorrect\n"); | |
315 | - early_iounmap(rsdt, sizeof(saved_rsdt)); | |
316 | - goto out_err; | |
317 | - } | |
318 | - | |
319 | - /* | |
320 | - * The number of tables is computed by taking the | |
321 | - * size of all entries (header size minus total | |
322 | - * size of RSDT) divided by the size of each entry | |
323 | - * (4-byte table pointers). | |
324 | - */ | |
325 | - tables = (header->length - sizeof(struct acpi_table_header)) / sizeof(u32); | |
326 | - | |
327 | - if (!tables) | |
328 | - goto out_err; | |
329 | - | |
330 | - memcpy(&saved_rsdt, rsdt, sizeof(saved_rsdt)); | |
331 | - early_iounmap(rsdt, sizeof(saved_rsdt)); | |
332 | - if (saved_rsdt.table.header.length > sizeof(saved_rsdt)) { | |
333 | - printk(KERN_WARNING "ACPI: Too big length in RSDT: %d\n", | |
334 | - saved_rsdt.table.header.length); | |
335 | - goto out_err; | |
336 | - } | |
337 | - | |
338 | - printk("Begin SRAT table scan....%d\n", tables); | |
339 | - | |
340 | - for (i = 0; i < tables; i++){ | |
341 | - int result; | |
342 | - u32 length; | |
343 | - /* Map in header, then map in full table length. */ | |
344 | - header = (struct acpi_table_header *) | |
345 | - early_ioremap(saved_rsdt.table.table_offset_entry[i], sizeof(struct acpi_table_header)); | |
346 | - if (!header) | |
347 | - break; | |
348 | - | |
349 | - printk(KERN_INFO "ACPI: %4.4s %08lX, %04X\n", | |
350 | - header->signature, | |
351 | - (unsigned long)saved_rsdt.table.table_offset_entry[i], | |
352 | - header->length); | |
353 | - | |
354 | - if (strncmp((char *) &header->signature, ACPI_SIG_SRAT, 4)) { | |
355 | - early_iounmap(header, sizeof(struct acpi_table_header)); | |
356 | - continue; | |
357 | - } | |
358 | - | |
359 | - length = header->length; | |
360 | - early_iounmap(header, sizeof(struct acpi_table_header)); | |
361 | - header = (struct acpi_table_header *) | |
362 | - early_ioremap(saved_rsdt.table.table_offset_entry[i], length); | |
363 | - if (!header) | |
364 | - break; | |
365 | - | |
366 | - /* we've found the srat table. don't need to look at any more tables */ | |
367 | - result = acpi20_parse_srat((struct acpi_table_srat *)header); | |
368 | - early_iounmap(header, length); | |
369 | - return result; | |
370 | - } | |
371 | -out_err: | |
372 | - remove_all_active_ranges(); | |
373 | 271 | printk("failed to get NUMA memory information from SRAT table\n"); |
374 | 272 | return 0; |
375 | 273 | } |
include/asm-x86/acpi.h
... | ... | @@ -161,9 +161,7 @@ |
161 | 161 | #ifdef CONFIG_ACPI_NUMA |
162 | 162 | extern int acpi_numa; |
163 | 163 | extern int acpi_scan_nodes(unsigned long start, unsigned long end); |
164 | -#ifdef CONFIG_X86_64 | |
165 | -# define NR_NODE_MEMBLKS (MAX_NUMNODES*2) | |
166 | -#endif | |
164 | +#define NR_NODE_MEMBLKS (MAX_NUMNODES*2) | |
167 | 165 | extern void acpi_fake_nodes(const struct bootnode *fake_nodes, |
168 | 166 | int num_nodes); |
169 | 167 | #else |
include/asm-x86/dmi.h
... | ... | @@ -3,12 +3,6 @@ |
3 | 3 | |
4 | 4 | #include <asm/io.h> |
5 | 5 | |
6 | -#ifdef CONFIG_X86_32 | |
7 | - | |
8 | -#define dmi_alloc alloc_bootmem | |
9 | - | |
10 | -#else /* CONFIG_X86_32 */ | |
11 | - | |
12 | 6 | #define DMI_MAX_DATA 2048 |
13 | 7 | |
14 | 8 | extern int dmi_alloc_index; |
... | ... | @@ -24,8 +18,6 @@ |
24 | 18 | dmi_alloc_index += len; |
25 | 19 | return dmi_alloc_data + idx; |
26 | 20 | } |
27 | - | |
28 | -#endif | |
29 | 21 | |
30 | 22 | /* Use early IO mappings for DMI because it's initialized early */ |
31 | 23 | #define dmi_ioremap early_ioremap |