this_cpu_*() ops will use it to get the local percpu address. It has the same value for all CPUs. Also introduce pcpu_local_base, which is the base address of local percpu map. Signed-off-by: Yang Shi --- arch/arm64/kernel/smp.c | 4 ++++ include/linux/percpu.h | 2 ++ mm/percpu.c | 3 +++ 3 files changed, 9 insertions(+) diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c index 4c112bab8356..4a811379c191 100644 --- a/arch/arm64/kernel/smp.c +++ b/arch/arm64/kernel/smp.c @@ -839,6 +839,9 @@ int early_cpu_to_node(int cpu) #ifdef CONFIG_HAVE_SETUP_PER_CPU_AREA unsigned long __per_cpu_offset[NR_CPUS] __read_mostly; EXPORT_SYMBOL(__per_cpu_offset); +/* Used to calculate pcpu local address, the offset is same for all CPUs */ +unsigned long __per_cpu_local_off __ro_after_init; +EXPORT_SYMBOL(__per_cpu_local_off); void __init setup_per_cpu_areas(void) { @@ -856,6 +859,7 @@ void __init setup_per_cpu_areas(void) delta = (unsigned long)pcpu_base_addr - (unsigned long)__per_cpu_start; for_each_possible_cpu(cpu) __per_cpu_offset[cpu] = delta + pcpu_unit_offsets[cpu]; + __per_cpu_local_off = (unsigned long)pcpu_local_base - (unsigned long)__per_cpu_start; } #endif diff --git a/include/linux/percpu.h b/include/linux/percpu.h index 2f0e190aca29..5a27031dff1a 100644 --- a/include/linux/percpu.h +++ b/include/linux/percpu.h @@ -75,6 +75,8 @@ extern void *pcpu_base_addr; extern const unsigned long *pcpu_unit_offsets; +/* percpu local mapping base */ +extern void *pcpu_local_base; struct pcpu_group_info { int nr_units; /* aligned # of units */ diff --git a/mm/percpu.c b/mm/percpu.c index 15303611ecaf..8b273ed8e5a8 100644 --- a/mm/percpu.c +++ b/mm/percpu.c @@ -145,6 +145,8 @@ static unsigned int pcpu_high_unit_cpu __ro_after_init; /* the address of the first chunk which starts with the kernel static area */ void *pcpu_base_addr __ro_after_init; +/* The address of the first chunk local mapping */ +void *pcpu_local_base __ro_after_init; static const int *pcpu_unit_map __ro_after_init; /* cpu -> unit */ const unsigned long *pcpu_unit_offsets __ro_after_init; /* cpu -> unit offset */ @@ -3305,6 +3307,7 @@ int __init pcpu_page_first_chunk(size_t reserved_size, pcpu_fc_cpu_to_node_fn_t ai->reserved_size, ai->dyn_size); pcpu_setup_first_chunk(ai, vm.addr, pcpu_vm.addr); + pcpu_local_base = pcpu_vm.addr; goto out_free_ar; enomem: -- 2.47.0