The atom_size used by percpu allocator on powerpc is currently determined by mmu_linear_psize which is initialized to 4K and mmu_linear_psize is modified only by hash. Till now for radix the atom_size was defaulting to PAGE_SIZE(64K). Go for 2MB atom_size on radix if support for 2MB pages exist.
2MB atom_size on radix will allow using PMD mappings in the vmalloc area if and when support for higher sized vmalloc mappings is enabled for the pecpu allocator. However right now this change will result in more number of units to be allocated within one allocation due to increased upa(units per allocation). Signed-off-by: Bharata B Rao <bhar...@linux.ibm.com> --- arch/powerpc/kernel/setup_64.c | 34 +++++++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c index 1ff258f6c76c..45ce2d6e8112 100644 --- a/arch/powerpc/kernel/setup_64.c +++ b/arch/powerpc/kernel/setup_64.c @@ -871,6 +871,30 @@ static void __init pcpu_populate_pte(unsigned long addr) __func__, PAGE_SIZE, PAGE_SIZE, PAGE_SIZE); } +static size_t pcpu_atom_size(void) +{ + size_t atom_size = PAGE_SIZE; + + /* + * Radix: Use PAGE_SIZE by default or 2M if available. + */ + if (radix_enabled()) { + if (mmu_psize_defs[MMU_PAGE_2M].shift) + atom_size = 1 << mmu_psize_defs[MMU_PAGE_2M].shift; + goto out; + } + + /* + * Hash: Linear mapping is one of 4K, 1M and 16M. For 4K, no need + * to group units. For larger mappings, use 1M atom which + * should be large enough to contain a number of units. + */ + if (mmu_linear_psize != MMU_PAGE_4K) + atom_size = 1 << 20; + +out: + return atom_size; +} void __init setup_per_cpu_areas(void) { @@ -880,15 +904,7 @@ void __init setup_per_cpu_areas(void) unsigned int cpu; int rc = -EINVAL; - /* - * Linear mapping is one of 4K, 1M and 16M. For 4K, no need - * to group units. For larger mappings, use 1M atom which - * should be large enough to contain a number of units. - */ - if (mmu_linear_psize == MMU_PAGE_4K) - atom_size = PAGE_SIZE; - else - atom_size = 1 << 20; + atom_size = pcpu_atom_size(); if (pcpu_chosen_fc != PCPU_FC_PAGE) { rc = pcpu_embed_first_chunk(0, dyn_size, atom_size, pcpu_cpu_distance, -- 2.31.1