簡體   English   中英

Linux內核中percpu指針是如何實現的?

[英]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提前給定的偏移量(以字節為單位)(無論指針類型如何)。

它有什么作用?

  1. 在定義DEFINE_PER_CPU(int, x) ,會在特殊的.data.percpu部分創建一個整數__per_cpu_x
  2. 當內核被加載時,這個部分被加載多次——每個 CPU 一次(這部分魔法不在上面的代碼中)。
  3. __per_cpu_offset數組填充了副本之間的距離。 假設使用 1000 字節的每個 cpu 數據, __per_cpu_offset[n]將包含1000*n
  4. 符號per_cpu__x將在加載期間重新定位到 CPU 0 的per_cpu__x
  5. __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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM