aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86')
-rw-r--r--arch/x86/kernel/setup_percpu.c38
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);
213out_free: 206out_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