aboutsummaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/sparc/kernel/smp_64.c24
-rw-r--r--arch/x86/kernel/setup_percpu.c38
2 files changed, 32 insertions, 30 deletions
diff --git a/arch/sparc/kernel/smp_64.c b/arch/sparc/kernel/smp_64.c
index 9856d866b77..a42a4a744d1 100644
--- a/arch/sparc/kernel/smp_64.c
+++ b/arch/sparc/kernel/smp_64.c
@@ -1475,17 +1475,29 @@ static void __init pcpu_map_range(unsigned long start, unsigned long end,
void __init setup_per_cpu_areas(void)
{
- size_t dyn_size, static_size = __per_cpu_end - __per_cpu_start;
static struct vm_struct vm;
+ struct pcpu_alloc_info *ai;
unsigned long delta, cpu;
size_t size_sum, pcpu_unit_size;
size_t ptrs_size;
void **ptrs;
- size_sum = PFN_ALIGN(static_size + PERCPU_MODULE_RESERVE +
+ ai = pcpu_alloc_alloc_info(1, nr_cpu_ids);
+
+ ai->static_size = __per_cpu_end - __per_cpu_start;
+ ai->reserved_size = PERCPU_MODULE_RESERVE;
+
+ size_sum = PFN_ALIGN(ai->static_size + ai->reserved_size +
PERCPU_DYNAMIC_RESERVE);
- dyn_size = size_sum - static_size - PERCPU_MODULE_RESERVE;
+ ai->dyn_size = size_sum - ai->static_size - ai->reserved_size;
+ ai->unit_size = PCPU_CHUNK_SIZE;
+ ai->atom_size = PCPU_CHUNK_SIZE;
+ ai->alloc_size = PCPU_CHUNK_SIZE;
+ ai->groups[0].nr_units = nr_cpu_ids;
+
+ for_each_possible_cpu(cpu)
+ ai->groups[0].cpu_map[cpu] = cpu;
ptrs_size = PFN_ALIGN(nr_cpu_ids * sizeof(ptrs[0]));
ptrs = alloc_bootmem(ptrs_size);
@@ -1497,7 +1509,7 @@ void __init setup_per_cpu_areas(void)
free_bootmem(__pa(ptrs[cpu] + size_sum),
PCPU_CHUNK_SIZE - size_sum);
- memcpy(ptrs[cpu], __per_cpu_load, static_size);
+ memcpy(ptrs[cpu], __per_cpu_load, ai->static_size);
}
/* allocate address and map */
@@ -1514,9 +1526,7 @@ void __init setup_per_cpu_areas(void)
pcpu_map_range(start, end, virt_to_page(ptrs[cpu]));
}
- pcpu_unit_size = pcpu_setup_first_chunk(static_size,
- PERCPU_MODULE_RESERVE, dyn_size,
- PCPU_CHUNK_SIZE, vm.addr, NULL);
+ pcpu_unit_size = pcpu_setup_first_chunk(ai, vm.addr);
free_bootmem(__pa(ptrs), ptrs_size);
diff --git a/arch/x86/kernel/setup_percpu.c b/arch/x86/kernel/setup_percpu.c
index 660cde13314..db5f9c49fec 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)
{
size_t reserve = PERCPU_MODULE_RESERVE + PERCPU_DYNAMIC_RESERVE;
size_t dyn_size = reserve - PERCPU_FIRST_CHUNK_RESERVE;
- size_t unit_map_size, unit_size;
- int *unit_map;
- int nr_units;
+ struct pcpu_alloc_info *ai;
ssize_t ret;
/* on non-NUMA, embedding is better */
@@ -177,26 +175,22 @@ static ssize_t __init setup_pcpu_lpage(bool chosen)
}
/* allocate and build unit_map */
- unit_map_size = nr_cpu_ids * sizeof(int);
- unit_map = alloc_bootmem_nopanic(unit_map_size);
- if (!unit_map) {
- pr_warning("PERCPU: failed to allocate unit_map\n");
- return -ENOMEM;
+ ai = pcpu_build_alloc_info(PERCPU_FIRST_CHUNK_RESERVE, dyn_size,
+ PMD_SIZE, pcpu_lpage_cpu_distance);
+ if (IS_ERR(ai)) {
+ pr_warning("PERCPU: failed to build unit_map (%ld)\n",
+ PTR_ERR(ai));
+ return PTR_ERR(ai);
}
- ret = pcpu_lpage_build_unit_map(PERCPU_FIRST_CHUNK_RESERVE,
- &dyn_size, &unit_size, PMD_SIZE,
- unit_map, pcpu_lpage_cpu_distance);
- if (ret < 0) {
- pr_warning("PERCPU: failed to build unit_map\n");
- goto out_free;
- }
- nr_units = ret;
-
/* do the parameters look okay? */
if (!chosen) {
size_t vm_size = VMALLOC_END - VMALLOC_START;
- size_t tot_size = nr_units * unit_size;
+ size_t tot_size = 0;
+ int group;
+
+ for (group = 0; group < ai->nr_groups; group++)
+ tot_size += ai->unit_size * ai->groups[group].nr_units;
/* don't consume more than 20% of vmalloc area */
if (tot_size > vm_size / 5) {
@@ -207,12 +201,10 @@ static ssize_t __init setup_pcpu_lpage(bool chosen)
}
}
- ret = pcpu_lpage_first_chunk(PERCPU_FIRST_CHUNK_RESERVE, dyn_size,
- unit_size, PMD_SIZE, unit_map, nr_units,
- pcpu_fc_alloc, pcpu_fc_free, pcpul_map);
+ ret = pcpu_lpage_first_chunk(ai, pcpu_fc_alloc, pcpu_fc_free,
+ pcpul_map);
out_free:
- if (ret < 0)
- free_bootmem(__pa(unit_map), unit_map_size);
+ pcpu_free_alloc_info(ai);
return ret;
}
#else