diff options
Diffstat (limited to 'arch/x86')
-rw-r--r-- | arch/x86/kernel/setup_percpu.c | 38 |
1 files changed, 15 insertions, 23 deletions
diff --git a/arch/x86/kernel/setup_percpu.c b/arch/x86/kernel/setup_percpu.c index 660cde133141..db5f9c49fec5 100644 --- a/arch/x86/kernel/setup_percpu.c +++ b/arch/x86/kernel/setup_percpu.c | |||
@@ -161,9 +161,7 @@ static ssize_t __init setup_pcpu_lpage(bool chosen) | |||
161 | { | 161 | { |
162 | size_t reserve = PERCPU_MODULE_RESERVE + PERCPU_DYNAMIC_RESERVE; | 162 | size_t reserve = PERCPU_MODULE_RESERVE + PERCPU_DYNAMIC_RESERVE; |
163 | size_t dyn_size = reserve - PERCPU_FIRST_CHUNK_RESERVE; | 163 | size_t dyn_size = reserve - PERCPU_FIRST_CHUNK_RESERVE; |
164 | size_t unit_map_size, unit_size; | 164 | struct pcpu_alloc_info *ai; |
165 | int *unit_map; | ||
166 | int nr_units; | ||
167 | ssize_t ret; | 165 | ssize_t ret; |
168 | 166 | ||
169 | /* on non-NUMA, embedding is better */ | 167 | /* on non-NUMA, embedding is better */ |
@@ -177,26 +175,22 @@ static ssize_t __init setup_pcpu_lpage(bool chosen) | |||
177 | } | 175 | } |
178 | 176 | ||
179 | /* allocate and build unit_map */ | 177 | /* allocate and build unit_map */ |
180 | unit_map_size = nr_cpu_ids * sizeof(int); | 178 | ai = pcpu_build_alloc_info(PERCPU_FIRST_CHUNK_RESERVE, dyn_size, |
181 | unit_map = alloc_bootmem_nopanic(unit_map_size); | 179 | PMD_SIZE, pcpu_lpage_cpu_distance); |
182 | if (!unit_map) { | 180 | if (IS_ERR(ai)) { |
183 | pr_warning("PERCPU: failed to allocate unit_map\n"); | 181 | pr_warning("PERCPU: failed to build unit_map (%ld)\n", |
184 | return -ENOMEM; | 182 | PTR_ERR(ai)); |
183 | return PTR_ERR(ai); | ||
185 | } | 184 | } |
186 | 185 | ||
187 | ret = pcpu_lpage_build_unit_map(PERCPU_FIRST_CHUNK_RESERVE, | ||
188 | &dyn_size, &unit_size, PMD_SIZE, | ||
189 | unit_map, pcpu_lpage_cpu_distance); | ||
190 | if (ret < 0) { | ||
191 | pr_warning("PERCPU: failed to build unit_map\n"); | ||
192 | goto out_free; | ||
193 | } | ||
194 | nr_units = ret; | ||
195 | |||
196 | /* do the parameters look okay? */ | 186 | /* do the parameters look okay? */ |
197 | if (!chosen) { | 187 | if (!chosen) { |
198 | size_t vm_size = VMALLOC_END - VMALLOC_START; | 188 | size_t vm_size = VMALLOC_END - VMALLOC_START; |
199 | size_t tot_size = nr_units * unit_size; | 189 | size_t tot_size = 0; |
190 | int group; | ||
191 | |||
192 | for (group = 0; group < ai->nr_groups; group++) | ||
193 | tot_size += ai->unit_size * ai->groups[group].nr_units; | ||
200 | 194 | ||
201 | /* don't consume more than 20% of vmalloc area */ | 195 | /* don't consume more than 20% of vmalloc area */ |
202 | if (tot_size > vm_size / 5) { | 196 | if (tot_size > vm_size / 5) { |
@@ -207,12 +201,10 @@ static ssize_t __init setup_pcpu_lpage(bool chosen) | |||
207 | } | 201 | } |
208 | } | 202 | } |
209 | 203 | ||
210 | ret = pcpu_lpage_first_chunk(PERCPU_FIRST_CHUNK_RESERVE, dyn_size, | 204 | ret = pcpu_lpage_first_chunk(ai, pcpu_fc_alloc, pcpu_fc_free, |
211 | unit_size, PMD_SIZE, unit_map, nr_units, | 205 | pcpul_map); |
212 | pcpu_fc_alloc, pcpu_fc_free, pcpul_map); | ||
213 | out_free: | 206 | out_free: |
214 | if (ret < 0) | 207 | pcpu_free_alloc_info(ai); |
215 | free_bootmem(__pa(unit_map), unit_map_size); | ||
216 | return ret; | 208 | return ret; |
217 | } | 209 | } |
218 | #else | 210 | #else |