per cpu variables
mostly copy-pasted from linux insides1. This is temporary. I’ll try to play with this hack later.
Each processor can have its own copy of a variable
-
The kernel creates multiple .data..percpu sections (one per-cpu) during initialization process;
-
All variables created with the
DEFINE_PER_CPU
macro will be relocated to the first section or for CPU0; -
__per_cpu_offset
array filled with the distance (BOOT_PERCPU_OFFSET) between .data..percpu sections; -
When the per_cpu_ptr is called, for example for getting a pointer on a certain per-cpu variable for the third CPU, the
__per_cpu_offset
array will be accessed, where every index points to the required CPU. -
there are other variants per config that put extra constraints (e.g.
ARCH_NEEDS_WEAK_PER_CPU
) -
behinds the scene: these are compiler with some compiler
§ definitions
macros2 defined in defined in
percpu-defs.h
#define DEFINE_PER_CPU(type, name) \
DEFINE_PER_CPU_SECTION(type, name, "")
// ...
#define DECLARE_PER_CPU_SECTION(type, name, sec) \
extern __PCPU_ATTRS(sec) __typeof__(type) name
#define DEFINE_PER_CPU_SECTION(type, name, sec) \
__PCPU_ATTRS(sec) __typeof__(type) name
#endif
after all macro expanded1
__attribute__((section(".data..percpu"))) type name
which creates a variable in section .data..percpu
. When the kernel initializes
it calls the
setup_per_cpu_areas
function which loads the .data..percpu
section multiple times, one section per CPU.1
$ dmesg | grep percpu
[ 0.043568] setup_percpu: NR_CPUS:320 nr_cpumask_bits:4 nr_cpu_ids:4 nr_node_ids:1
[ 0.044069] percpu: Embedded 64 pages/cpu s225280 r8192 d28672 u524288
reference and license:
§ What per-cpu variables are there?
// arch/x86/include/asm/preempt.h
DECLARE_PER_CPU(int, __preempt_count);
// arch/x86/include/asm/current.h
// a per-cpu pointer to the currently running task struct
// NOTE: this are changed (packed into a struct pcpu_hot) with patch
// x86: Put hot per CPU variables into a struct
DECLARE_PER_CPU(struct task_struct *, current_task);
§ TODO: play with this locally…
-
https://github.com/0xAX/linux-insides : CC-BY-NC-SA-4.0 ↩︎ ↩︎ ↩︎
-
anything from linux source tree / mailinglist : GPL-2.0-only ↩︎