diff options
-rw-r--r-- | arch/ia64/Kconfig | 3 | ||||
-rw-r--r-- | arch/ia64/kernel/setup.c | 12 | ||||
-rw-r--r-- | arch/ia64/mm/contig.c | 58 | ||||
-rw-r--r-- | arch/ia64/mm/discontig.c | 85 |
4 files changed, 138 insertions, 20 deletions
diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig index 1ee596cd942f..2d7f56a98e0f 100644 --- a/arch/ia64/Kconfig +++ b/arch/ia64/Kconfig | |||
@@ -87,9 +87,6 @@ config GENERIC_TIME_VSYSCALL | |||
87 | bool | 87 | bool |
88 | default y | 88 | default y |
89 | 89 | ||
90 | config HAVE_LEGACY_PER_CPU_AREA | ||
91 | def_bool y | ||
92 | |||
93 | config HAVE_SETUP_PER_CPU_AREA | 90 | config HAVE_SETUP_PER_CPU_AREA |
94 | def_bool y | 91 | def_bool y |
95 | 92 | ||
diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c index 5d77c1e1c0ce..bc1ef4ae828c 100644 --- a/arch/ia64/kernel/setup.c +++ b/arch/ia64/kernel/setup.c | |||
@@ -855,18 +855,6 @@ identify_cpu (struct cpuinfo_ia64 *c) | |||
855 | } | 855 | } |
856 | 856 | ||
857 | /* | 857 | /* |
858 | * In UP configuration, setup_per_cpu_areas() is defined in | ||
859 | * include/linux/percpu.h | ||
860 | */ | ||
861 | #ifdef CONFIG_SMP | ||
862 | void __init | ||
863 | setup_per_cpu_areas (void) | ||
864 | { | ||
865 | /* start_kernel() requires this... */ | ||
866 | } | ||
867 | #endif | ||
868 | |||
869 | /* | ||
870 | * Do the following calculations: | 858 | * Do the following calculations: |
871 | * | 859 | * |
872 | * 1. the max. cache line size. | 860 | * 1. the max. cache line size. |
diff --git a/arch/ia64/mm/contig.c b/arch/ia64/mm/contig.c index 351da0a06cd0..54bf54059811 100644 --- a/arch/ia64/mm/contig.c +++ b/arch/ia64/mm/contig.c | |||
@@ -163,11 +163,11 @@ per_cpu_init (void) | |||
163 | first_time = false; | 163 | first_time = false; |
164 | 164 | ||
165 | /* | 165 | /* |
166 | * get_free_pages() cannot be used before cpu_init() done. BSP | 166 | * get_free_pages() cannot be used before cpu_init() done. |
167 | * allocates "NR_CPUS" pages for all CPUs to avoid that AP calls | 167 | * BSP allocates PERCPU_PAGE_SIZE bytes for all possible CPUs |
168 | * get_zeroed_page(). | 168 | * to avoid that AP calls get_zeroed_page(). |
169 | */ | 169 | */ |
170 | for (cpu = 0; cpu < NR_CPUS; cpu++) { | 170 | for_each_possible_cpu(cpu) { |
171 | void *src = cpu == 0 ? cpu0_data : __phys_per_cpu_start; | 171 | void *src = cpu == 0 ? cpu0_data : __phys_per_cpu_start; |
172 | 172 | ||
173 | memcpy(cpu_data, src, __per_cpu_end - __per_cpu_start); | 173 | memcpy(cpu_data, src, __per_cpu_end - __per_cpu_start); |
@@ -196,9 +196,57 @@ skip: | |||
196 | static inline void | 196 | static inline void |
197 | alloc_per_cpu_data(void) | 197 | alloc_per_cpu_data(void) |
198 | { | 198 | { |
199 | cpu_data = __alloc_bootmem(PERCPU_PAGE_SIZE * NR_CPUS, | 199 | cpu_data = __alloc_bootmem(PERCPU_PAGE_SIZE * num_possible_cpus(), |
200 | PERCPU_PAGE_SIZE, __pa(MAX_DMA_ADDRESS)); | 200 | PERCPU_PAGE_SIZE, __pa(MAX_DMA_ADDRESS)); |
201 | } | 201 | } |
202 | |||
203 | /** | ||
204 | * setup_per_cpu_areas - setup percpu areas | ||
205 | * | ||
206 | * Arch code has already allocated and initialized percpu areas. All | ||
207 | * this function has to do is to teach the determined layout to the | ||
208 | * dynamic percpu allocator, which happens to be more complex than | ||
209 | * creating whole new ones using helpers. | ||
210 | */ | ||
211 | void __init | ||
212 | setup_per_cpu_areas(void) | ||
213 | { | ||
214 | struct pcpu_alloc_info *ai; | ||
215 | struct pcpu_group_info *gi; | ||
216 | unsigned int cpu; | ||
217 | ssize_t static_size, reserved_size, dyn_size; | ||
218 | int rc; | ||
219 | |||
220 | ai = pcpu_alloc_alloc_info(1, num_possible_cpus()); | ||
221 | if (!ai) | ||
222 | panic("failed to allocate pcpu_alloc_info"); | ||
223 | gi = &ai->groups[0]; | ||
224 | |||
225 | /* units are assigned consecutively to possible cpus */ | ||
226 | for_each_possible_cpu(cpu) | ||
227 | gi->cpu_map[gi->nr_units++] = cpu; | ||
228 | |||
229 | /* set parameters */ | ||
230 | static_size = __per_cpu_end - __per_cpu_start; | ||
231 | reserved_size = PERCPU_MODULE_RESERVE; | ||
232 | dyn_size = PERCPU_PAGE_SIZE - static_size - reserved_size; | ||
233 | if (dyn_size < 0) | ||
234 | panic("percpu area overflow static=%zd reserved=%zd\n", | ||
235 | static_size, reserved_size); | ||
236 | |||
237 | ai->static_size = static_size; | ||
238 | ai->reserved_size = reserved_size; | ||
239 | ai->dyn_size = dyn_size; | ||
240 | ai->unit_size = PERCPU_PAGE_SIZE; | ||
241 | ai->atom_size = PAGE_SIZE; | ||
242 | ai->alloc_size = PERCPU_PAGE_SIZE; | ||
243 | |||
244 | rc = pcpu_setup_first_chunk(ai, __per_cpu_start + __per_cpu_offset[0]); | ||
245 | if (rc) | ||
246 | panic("failed to setup percpu area (err=%d)", rc); | ||
247 | |||
248 | pcpu_free_alloc_info(ai); | ||
249 | } | ||
202 | #else | 250 | #else |
203 | #define alloc_per_cpu_data() do { } while (0) | 251 | #define alloc_per_cpu_data() do { } while (0) |
204 | #endif /* CONFIG_SMP */ | 252 | #endif /* CONFIG_SMP */ |
diff --git a/arch/ia64/mm/discontig.c b/arch/ia64/mm/discontig.c index 200282b92981..40e4c1fbf76b 100644 --- a/arch/ia64/mm/discontig.c +++ b/arch/ia64/mm/discontig.c | |||
@@ -172,6 +172,91 @@ static void *per_cpu_node_setup(void *cpu_data, int node) | |||
172 | return cpu_data; | 172 | return cpu_data; |
173 | } | 173 | } |
174 | 174 | ||
175 | #ifdef CONFIG_SMP | ||
176 | /** | ||
177 | * setup_per_cpu_areas - setup percpu areas | ||
178 | * | ||
179 | * Arch code has already allocated and initialized percpu areas. All | ||
180 | * this function has to do is to teach the determined layout to the | ||
181 | * dynamic percpu allocator, which happens to be more complex than | ||
182 | * creating whole new ones using helpers. | ||
183 | */ | ||
184 | void __init setup_per_cpu_areas(void) | ||
185 | { | ||
186 | struct pcpu_alloc_info *ai; | ||
187 | struct pcpu_group_info *uninitialized_var(gi); | ||
188 | unsigned int *cpu_map; | ||
189 | void *base; | ||
190 | unsigned long base_offset; | ||
191 | unsigned int cpu; | ||
192 | ssize_t static_size, reserved_size, dyn_size; | ||
193 | int node, prev_node, unit, nr_units, rc; | ||
194 | |||
195 | ai = pcpu_alloc_alloc_info(MAX_NUMNODES, nr_cpu_ids); | ||
196 | if (!ai) | ||
197 | panic("failed to allocate pcpu_alloc_info"); | ||
198 | cpu_map = ai->groups[0].cpu_map; | ||
199 | |||
200 | /* determine base */ | ||
201 | base = (void *)ULONG_MAX; | ||
202 | for_each_possible_cpu(cpu) | ||
203 | base = min(base, | ||
204 | (void *)(__per_cpu_offset[cpu] + __per_cpu_start)); | ||
205 | base_offset = (void *)__per_cpu_start - base; | ||
206 | |||
207 | /* build cpu_map, units are grouped by node */ | ||
208 | unit = 0; | ||
209 | for_each_node(node) | ||
210 | for_each_possible_cpu(cpu) | ||
211 | if (node == node_cpuid[cpu].nid) | ||
212 | cpu_map[unit++] = cpu; | ||
213 | nr_units = unit; | ||
214 | |||
215 | /* set basic parameters */ | ||
216 | static_size = __per_cpu_end - __per_cpu_start; | ||
217 | reserved_size = PERCPU_MODULE_RESERVE; | ||
218 | dyn_size = PERCPU_PAGE_SIZE - static_size - reserved_size; | ||
219 | if (dyn_size < 0) | ||
220 | panic("percpu area overflow static=%zd reserved=%zd\n", | ||
221 | static_size, reserved_size); | ||
222 | |||
223 | ai->static_size = static_size; | ||
224 | ai->reserved_size = reserved_size; | ||
225 | ai->dyn_size = dyn_size; | ||
226 | ai->unit_size = PERCPU_PAGE_SIZE; | ||
227 | ai->atom_size = PAGE_SIZE; | ||
228 | ai->alloc_size = PERCPU_PAGE_SIZE; | ||
229 | |||
230 | /* | ||
231 | * CPUs are put into groups according to node. Walk cpu_map | ||
232 | * and create new groups at node boundaries. | ||
233 | */ | ||
234 | prev_node = -1; | ||
235 | ai->nr_groups = 0; | ||
236 | for (unit = 0; unit < nr_units; unit++) { | ||
237 | cpu = cpu_map[unit]; | ||
238 | node = node_cpuid[cpu].nid; | ||
239 | |||
240 | if (node == prev_node) { | ||
241 | gi->nr_units++; | ||
242 | continue; | ||
243 | } | ||
244 | prev_node = node; | ||
245 | |||
246 | gi = &ai->groups[ai->nr_groups++]; | ||
247 | gi->nr_units = 1; | ||
248 | gi->base_offset = __per_cpu_offset[cpu] + base_offset; | ||
249 | gi->cpu_map = &cpu_map[unit]; | ||
250 | } | ||
251 | |||
252 | rc = pcpu_setup_first_chunk(ai, base); | ||
253 | if (rc) | ||
254 | panic("failed to setup percpu area (err=%d)", rc); | ||
255 | |||
256 | pcpu_free_alloc_info(ai); | ||
257 | } | ||
258 | #endif | ||
259 | |||
175 | /** | 260 | /** |
176 | * fill_pernode - initialize pernode data. | 261 | * fill_pernode - initialize pernode data. |
177 | * @node: the node id. | 262 | * @node: the node id. |