[英]How are percpu pointers implemented in the Linux kernel?
在多處理器上,每個內核都可以有自己的變量。 我認為它們是不同地址的不同變量,盡管它們在同一個進程中並且具有相同的名稱。
但我想知道,內核是如何實現這一點的? 它是否分配了一塊內存來存放所有的 percpu 指針,並且每次它將指針重定向到某個地址時使用 shift 或其他什么?
普通全局變量不是每個 CPU。 自動變量在棧上,不同的CPU使用不同的棧,所以自然會得到不同的變量。
我猜你指的是 Linux 的每 CPU 可變基礎設施。
大部分魔法都在這里( asm-generic/percpu.h
):
extern unsigned long __per_cpu_offset[NR_CPUS];
#define per_cpu_offset(x) (__per_cpu_offset[x])
/* Separate out the type, so (int[3], foo) works. */
#define DEFINE_PER_CPU(type, name) \
__attribute__((__section__(".data.percpu"))) __typeof__(type) per_cpu__##name
/* var is in discarded region: offset to particular copy we want */
#define per_cpu(var, cpu) (*RELOC_HIDE(&per_cpu__##var, __per_cpu_offset[cpu]))
#define __get_cpu_var(var) per_cpu(var, smp_processor_id())
宏RELOC_HIDE(ptr, offset)
只是將ptr
提前給定的偏移量(以字節為單位)(無論指針類型如何)。
它有什么作用?
DEFINE_PER_CPU(int, x)
,會在特殊的.data.percpu
部分創建一個整數__per_cpu_x
。__per_cpu_offset
數組填充了副本之間的距離。 假設使用 1000 字節的每個 cpu 數據, __per_cpu_offset[n]
將包含1000*n
。per_cpu__x
將在加載期間重新定位到 CPU 0 的per_cpu__x
。__get_cpu_var(x)
在 CPU 3 上運行時,將轉換為*RELOC_HIDE(&per_cpu__x, __per_cpu_offset[3])
。 這從 CPU 0 的x
,添加 CPU 0 的數據和 CPU 3 之間的偏移量,並最終取消引用結果指針。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.