diff options
author | travis@sgi.com <travis@sgi.com> | 2008-01-30 07:33:21 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-01-30 07:33:21 -0500 |
commit | 834beda15ecc43c110c0a6ac39ec1aa79f891716 (patch) | |
tree | 56f00ac3e1b06083c5be928dc740369a022b76fa | |
parent | ac72e7888a612dccfbc15b34698aad441bdfda10 (diff) |
x86: change NR_CPUS arrays in numa_64 fixup
Change the following static arrays sized by NR_CPUS to
per_cpu data variables:
char cpu_to_node_map[NR_CPUS];
fixup:
- Split cpu_to_node function into "early" and "late" versions
so that x86_cpu_to_node_map_early_ptr is not EXPORT'ed and
the cpu_to_node inline function is more streamlined.
- This also involves setting up the percpu maps as early as possible.
- Fix X86_32 NUMA build errors that previous version of this
patch caused.
V2->V3:
- add early_cpu_to_node function to keep cpu_to_node efficient
- move and rename smp_set_apicids() to setup_percpu_maps()
- call setup_percpu_maps() as early as possible
V1->V2:
- Removed extraneous casts
- Fix !NUMA builds with '#ifdef CONFIG_NUMA"
Signed-off-by: Mike Travis <travis@sgi.com>
Reviewed-by: Christoph Lameter <clameter@sgi.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
-rw-r--r-- | arch/x86/kernel/setup64.c | 41 | ||||
-rw-r--r-- | arch/x86/kernel/smpboot_32.c | 2 | ||||
-rw-r--r-- | arch/x86/kernel/smpboot_64.c | 34 | ||||
-rw-r--r-- | arch/x86/mm/srat_64.c | 5 | ||||
-rw-r--r-- | include/asm-x86/topology.h | 23 |
5 files changed, 66 insertions, 39 deletions
diff --git a/arch/x86/kernel/setup64.c b/arch/x86/kernel/setup64.c index 8fa0de810d0b..855ec82e4f76 100644 --- a/arch/x86/kernel/setup64.c +++ b/arch/x86/kernel/setup64.c | |||
@@ -84,6 +84,40 @@ static int __init nonx32_setup(char *str) | |||
84 | __setup("noexec32=", nonx32_setup); | 84 | __setup("noexec32=", nonx32_setup); |
85 | 85 | ||
86 | /* | 86 | /* |
87 | * Copy data used in early init routines from the initial arrays to the | ||
88 | * per cpu data areas. These arrays then become expendable and the *_ptrs | ||
89 | * are zeroed indicating that the static arrays are gone. | ||
90 | */ | ||
91 | void __init setup_percpu_maps(void) | ||
92 | { | ||
93 | int cpu; | ||
94 | |||
95 | for_each_possible_cpu(cpu) { | ||
96 | #ifdef CONFIG_SMP | ||
97 | if (per_cpu_offset(cpu)) { | ||
98 | #endif | ||
99 | per_cpu(x86_cpu_to_apicid, cpu) = | ||
100 | x86_cpu_to_apicid_init[cpu]; | ||
101 | #ifdef CONFIG_NUMA | ||
102 | per_cpu(x86_cpu_to_node_map, cpu) = | ||
103 | x86_cpu_to_node_map_init[cpu]; | ||
104 | #endif | ||
105 | #ifdef CONFIG_SMP | ||
106 | } | ||
107 | else | ||
108 | printk(KERN_NOTICE "per_cpu_offset zero for cpu %d\n", | ||
109 | cpu); | ||
110 | #endif | ||
111 | } | ||
112 | |||
113 | /* indicate the early static arrays are gone */ | ||
114 | x86_cpu_to_apicid_early_ptr = NULL; | ||
115 | #ifdef CONFIG_NUMA | ||
116 | x86_cpu_to_node_map_early_ptr = NULL; | ||
117 | #endif | ||
118 | } | ||
119 | |||
120 | /* | ||
87 | * Great future plan: | 121 | * Great future plan: |
88 | * Declare PDA itself and support (irqstack,tss,pgd) as per cpu data. | 122 | * Declare PDA itself and support (irqstack,tss,pgd) as per cpu data. |
89 | * Always point %gs to its beginning | 123 | * Always point %gs to its beginning |
@@ -104,18 +138,21 @@ void __init setup_per_cpu_areas(void) | |||
104 | for_each_cpu_mask (i, cpu_possible_map) { | 138 | for_each_cpu_mask (i, cpu_possible_map) { |
105 | char *ptr; | 139 | char *ptr; |
106 | 140 | ||
107 | if (!NODE_DATA(cpu_to_node(i))) { | 141 | if (!NODE_DATA(early_cpu_to_node(i))) { |
108 | printk("cpu with no node %d, num_online_nodes %d\n", | 142 | printk("cpu with no node %d, num_online_nodes %d\n", |
109 | i, num_online_nodes()); | 143 | i, num_online_nodes()); |
110 | ptr = alloc_bootmem_pages(size); | 144 | ptr = alloc_bootmem_pages(size); |
111 | } else { | 145 | } else { |
112 | ptr = alloc_bootmem_pages_node(NODE_DATA(cpu_to_node(i)), size); | 146 | ptr = alloc_bootmem_pages_node(NODE_DATA(early_cpu_to_node(i)), size); |
113 | } | 147 | } |
114 | if (!ptr) | 148 | if (!ptr) |
115 | panic("Cannot allocate cpu data for CPU %d\n", i); | 149 | panic("Cannot allocate cpu data for CPU %d\n", i); |
116 | cpu_pda(i)->data_offset = ptr - __per_cpu_start; | 150 | cpu_pda(i)->data_offset = ptr - __per_cpu_start; |
117 | memcpy(ptr, __per_cpu_start, __per_cpu_end - __per_cpu_start); | 151 | memcpy(ptr, __per_cpu_start, __per_cpu_end - __per_cpu_start); |
118 | } | 152 | } |
153 | |||
154 | /* setup percpu data maps early */ | ||
155 | setup_percpu_maps(); | ||
119 | } | 156 | } |
120 | 157 | ||
121 | void pda_init(int cpu) | 158 | void pda_init(int cpu) |
diff --git a/arch/x86/kernel/smpboot_32.c b/arch/x86/kernel/smpboot_32.c index 915ec6267326..50232d476a27 100644 --- a/arch/x86/kernel/smpboot_32.c +++ b/arch/x86/kernel/smpboot_32.c | |||
@@ -465,7 +465,7 @@ cpumask_t node_to_cpumask_map[MAX_NUMNODES] __read_mostly = | |||
465 | { [0 ... MAX_NUMNODES-1] = CPU_MASK_NONE }; | 465 | { [0 ... MAX_NUMNODES-1] = CPU_MASK_NONE }; |
466 | EXPORT_SYMBOL(node_to_cpumask_map); | 466 | EXPORT_SYMBOL(node_to_cpumask_map); |
467 | /* which node each logical CPU is on */ | 467 | /* which node each logical CPU is on */ |
468 | int cpu_to_node_map[NR_CPUS] __read_mostly = { [0 ... NR_CPUS-1] = 0 }; | 468 | u8 cpu_to_node_map[NR_CPUS] __read_mostly = { [0 ... NR_CPUS-1] = 0 }; |
469 | EXPORT_SYMBOL(cpu_to_node_map); | 469 | EXPORT_SYMBOL(cpu_to_node_map); |
470 | 470 | ||
471 | /* set up a mapping between cpu and node. */ | 471 | /* set up a mapping between cpu and node. */ |
diff --git a/arch/x86/kernel/smpboot_64.c b/arch/x86/kernel/smpboot_64.c index 93071cdf0849..4e14ecb90764 100644 --- a/arch/x86/kernel/smpboot_64.c +++ b/arch/x86/kernel/smpboot_64.c | |||
@@ -851,39 +851,6 @@ static int __init smp_sanity_check(unsigned max_cpus) | |||
851 | return 0; | 851 | return 0; |
852 | } | 852 | } |
853 | 853 | ||
854 | /* | ||
855 | * Copy data used in early init routines from the initial arrays to the | ||
856 | * per cpu data areas. These arrays then become expendable and the | ||
857 | * *_ptrs are zeroed indicating that the static arrays are gone. | ||
858 | */ | ||
859 | void __init smp_set_apicids(void) | ||
860 | { | ||
861 | int cpu; | ||
862 | |||
863 | for_each_possible_cpu(cpu) { | ||
864 | if (per_cpu_offset(cpu)) { | ||
865 | per_cpu(x86_cpu_to_apicid, cpu) = | ||
866 | x86_cpu_to_apicid_init[cpu]; | ||
867 | #ifdef CONFIG_NUMA | ||
868 | per_cpu(x86_cpu_to_node_map, cpu) = | ||
869 | x86_cpu_to_node_map_init[cpu]; | ||
870 | #endif | ||
871 | per_cpu(x86_bios_cpu_apicid, cpu) = | ||
872 | x86_bios_cpu_apicid_init[cpu]; | ||
873 | } | ||
874 | else | ||
875 | printk(KERN_NOTICE "per_cpu_offset zero for cpu %d\n", | ||
876 | cpu); | ||
877 | } | ||
878 | |||
879 | /* indicate the early static arrays are gone */ | ||
880 | x86_cpu_to_apicid_early_ptr = NULL; | ||
881 | #ifdef CONFIG_NUMA | ||
882 | x86_cpu_to_node_map_early_ptr = NULL; | ||
883 | #endif | ||
884 | x86_bios_cpu_apicid_early_ptr = NULL; | ||
885 | } | ||
886 | |||
887 | static void __init smp_cpu_index_default(void) | 854 | static void __init smp_cpu_index_default(void) |
888 | { | 855 | { |
889 | int i; | 856 | int i; |
@@ -906,7 +873,6 @@ void __init smp_prepare_cpus(unsigned int max_cpus) | |||
906 | smp_cpu_index_default(); | 873 | smp_cpu_index_default(); |
907 | current_cpu_data = boot_cpu_data; | 874 | current_cpu_data = boot_cpu_data; |
908 | current_thread_info()->cpu = 0; /* needed? */ | 875 | current_thread_info()->cpu = 0; /* needed? */ |
909 | smp_set_apicids(); | ||
910 | set_cpu_sibling_map(0); | 876 | set_cpu_sibling_map(0); |
911 | 877 | ||
912 | if (smp_sanity_check(max_cpus) < 0) { | 878 | if (smp_sanity_check(max_cpus) < 0) { |
diff --git a/arch/x86/mm/srat_64.c b/arch/x86/mm/srat_64.c index e5a1ec8342dc..04cbecaeca81 100644 --- a/arch/x86/mm/srat_64.c +++ b/arch/x86/mm/srat_64.c | |||
@@ -382,9 +382,10 @@ int __init acpi_scan_nodes(unsigned long start, unsigned long end) | |||
382 | setup_node_bootmem(i, nodes[i].start, nodes[i].end); | 382 | setup_node_bootmem(i, nodes[i].start, nodes[i].end); |
383 | 383 | ||
384 | for (i = 0; i < NR_CPUS; i++) { | 384 | for (i = 0; i < NR_CPUS; i++) { |
385 | if (cpu_to_node(i) == NUMA_NO_NODE) | 385 | int node = cpu_to_node(i); |
386 | if (node == NUMA_NO_NODE) | ||
386 | continue; | 387 | continue; |
387 | if (!node_isset(cpu_to_node(i), node_possible_map)) | 388 | if (!node_isset(node, node_possible_map)) |
388 | numa_set_node(i, NUMA_NO_NODE); | 389 | numa_set_node(i, NUMA_NO_NODE); |
389 | } | 390 | } |
390 | numa_init_array(); | 391 | numa_init_array(); |
diff --git a/include/asm-x86/topology.h b/include/asm-x86/topology.h index 2da1464ecbef..040374f030cf 100644 --- a/include/asm-x86/topology.h +++ b/include/asm-x86/topology.h | |||
@@ -30,16 +30,30 @@ | |||
30 | #include <asm/mpspec.h> | 30 | #include <asm/mpspec.h> |
31 | 31 | ||
32 | /* Mappings between logical cpu number and node number */ | 32 | /* Mappings between logical cpu number and node number */ |
33 | #ifdef CONFIG_X86_32 | ||
34 | extern u8 cpu_to_node_map[]; | ||
35 | |||
36 | #else | ||
33 | DECLARE_PER_CPU(u16, x86_cpu_to_node_map); | 37 | DECLARE_PER_CPU(u16, x86_cpu_to_node_map); |
34 | extern u16 x86_cpu_to_node_map_init[]; | 38 | extern u16 x86_cpu_to_node_map_init[]; |
35 | extern void *x86_cpu_to_node_map_early_ptr; | 39 | extern void *x86_cpu_to_node_map_early_ptr; |
40 | #endif | ||
41 | |||
36 | extern cpumask_t node_to_cpumask_map[]; | 42 | extern cpumask_t node_to_cpumask_map[]; |
37 | 43 | ||
38 | #define NUMA_NO_NODE ((u16)(~0)) | 44 | #define NUMA_NO_NODE ((u16)(~0)) |
39 | 45 | ||
40 | /* Returns the number of the node containing CPU 'cpu' */ | 46 | /* Returns the number of the node containing CPU 'cpu' */ |
47 | #ifdef CONFIG_X86_32 | ||
48 | #define early_cpu_to_node(cpu) cpu_to_node(cpu) | ||
41 | static inline int cpu_to_node(int cpu) | 49 | static inline int cpu_to_node(int cpu) |
42 | { | 50 | { |
51 | return cpu_to_node_map[cpu]; | ||
52 | } | ||
53 | |||
54 | #else /* CONFIG_X86_64 */ | ||
55 | static inline int early_cpu_to_node(int cpu) | ||
56 | { | ||
43 | u16 *cpu_to_node_map = x86_cpu_to_node_map_early_ptr; | 57 | u16 *cpu_to_node_map = x86_cpu_to_node_map_early_ptr; |
44 | 58 | ||
45 | if (cpu_to_node_map) | 59 | if (cpu_to_node_map) |
@@ -50,6 +64,15 @@ static inline int cpu_to_node(int cpu) | |||
50 | return NUMA_NO_NODE; | 64 | return NUMA_NO_NODE; |
51 | } | 65 | } |
52 | 66 | ||
67 | static inline int cpu_to_node(int cpu) | ||
68 | { | ||
69 | if(per_cpu_offset(cpu)) | ||
70 | return per_cpu(x86_cpu_to_node_map, cpu); | ||
71 | else | ||
72 | return NUMA_NO_NODE; | ||
73 | } | ||
74 | #endif /* CONFIG_X86_64 */ | ||
75 | |||
53 | /* | 76 | /* |
54 | * Returns the number of the node containing Node 'node'. This | 77 | * Returns the number of the node containing Node 'node'. This |
55 | * architecture is flat, so it is a pretty simple function! | 78 | * architecture is flat, so it is a pretty simple function! |