Commit 1c6e55032e24ff79668581a0f296c278ef7edd4e

Authored by Yinghai Lu
Committed by Ingo Molnar
1 parent 0699eae140

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