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 4caa6ebec12f..62afabf86ba1 100644 --- a/arch/arm64/kernel/smp.c +++ b/arch/arm64/kernel/smp.c @@ -825,6 +825,9 @@ extern int cpu_to_node_map[NR_CPUS]; 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 __read_mostly; +EXPORT_SYMBOL(__per_cpu_local_off); int early_cpu_to_node(int cpu) { @@ -847,6 +850,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; } static const char *ipi_types[MAX_IPI] __tracepoint_string = { diff --git a/include/linux/percpu.h b/include/linux/percpu.h index dba050f5b548..e29ebd265087 100644 --- a/include/linux/percpu.h +++ b/include/linux/percpu.h @@ -74,6 +74,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 5148c5ccf9e3..17d0c2b0de5a 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 */ @@ -3297,6 +3299,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