针对IA64体系结构
在Linux操作系统中,特别是针对SMP或者NUMA架构的多CPU系统的时候,描述每个CPU的私有数据的时候,Linux操作系统提供了per_cpu机制。
per_cpu机制就是让每个CPU都有自己的私有数据段,便于保护与访问。
通过宏DEFINE_PER_CPU,定义这种私有数据,只不过这种私有数据放在特定的数据段中。
#define DEFINE_PER_CPU(type, name) \
__attribute__((__section__(“.data.percpu”))) \
PER_CPU_ATTRIBUTES __typeof__(type) per_cpu__##name
在GCC中__typeof__相当于typeof(检查数据类型),用__typeof__为了兼容性。
例如1:在Linux操作系统中,用于描述每个IA64CPU信息的数据结构的定义:
DEFINE_PER_CPU(struct cpuinfo_ia64, cpu_info);
例如2:描述每个CPU的状态的变量的定义:*
* State for each CPU
*/
DEFINE_PER_CPU(int, cpu_state);
系统如何为每个CPU保留这些私有数据的?
在start_kernel函数中调用执行函数setup_per_cpu_areas( ),setup_per_cpu_areas( )定义如下:
static void __init setup_per_cpu_areas(void)
{
unsigned long size, i;
char *ptr;
unsigned long nr_possible_cpus = num_possible_cpus();
/* Copy section for each CPU (we discard the original) */
size = ALIGN(PERCPU_ENOUGH_ROOM, PAGE_SIZE);
ptr = alloc_bootmem_pages(size * nr_possible_cpus);
for_each_possible_cpu(i) {
__per_cpu_offset = ptr – __per_cpu_start;
memcpy(ptr, __per_cpu_start, __per_cpu_end – __per_cpu_start);
ptr += size;
}
}
setup_per_cpu_areas( )的功能就是将.data.percpu中的数据拷贝到每个CPU的数据段中,每个CPU一份。
其中CPU n 对应的专有数据区的首地址为__per_cpu_offset[n]。
在Linux操作系统中,在系统启动的时候会生成以__per_cpu_start标识开头和__per_cpu_end标识结尾的数据段,在执行完函数setup_per_cpu_areas( )后,将.data.percpu中的数据拷贝到每个CPU数据段后,这个数据段就会释放(free)掉。
.data.percpu定义如下(在arch/ia64/kernel/vmlinux.lds.S):
{
__per_cpu_start = .;
*(.data.percpu)
*(.data.percpu.shared_aligned)
__per_cpu_end = .;
}
如何存取每个CPU的这些私有数据呢?
第一种方法:取制定cpu的制定变量
/*
* A percpu variable may point to a discarded regions. The following are
* established ways to produce a usable pointer from the percpu variable
* offset.
*/
#define per_cpu(var, cpu) \
(*SHIFT_PERCPU_PTR(&per_cpu_var(var), per_cpu_offset(cpu)))
|
|
#define SHIFT_PERCPU_PTR(__p, __offset) RELOC_HIDE((__p), (__offset))
|
|
#define RELOC_HIDE(ptr, off) \
({ unsigned long __ptr; \
__asm__ (“” : “=r”(__ptr) : “0”(ptr)); \
(typeof(ptr)) (__ptr + (off)); })
第二种方法:取当前CPU的制定变量
#define __get_cpu_var(var) \
(*SHIFT_PERCPU_PTR(&per_cpu_var(var), my_cpu_offset))
第三种方法:读后写的方式读取当前CPU的制定变量
#define __raw_get_cpu_var(var) \
(*SHIFT_PERCPU_PTR(&per_cpu_var(var), __my_cpu_offset))
Linux per_cpu机制的详解
转载请注明出处:服务器评测 » Linux per_cpu机制的详解
相关推荐
- MinRTT 达拉斯VPS:免费送IPv4、EPYC高性能处理器、50Gbps大带宽LACP、3天无理由退款、即时部署
- 热门EPYC与双路E5独服现货秒发:100G带宽、无需等待装机、即买即用
- 【全球加速】米兰服务器正式上线|22大数据中心|4000台独享服务器秒级部署
- 《限时特惠$40起!ARP Thunder™独立服务器:4GB内存 + 80GB SSD + 200GB SATA + 5TB流量,超值爆发》
- PacketRa 芬兰独立服务器 —— 注重隐私保护,支持加密货币支付 —— 限时立减$15-$150 ✅
- Spin Servers 火热促销中!硅谷独立服务器,10Gbps大带宽,仅需$75/月起,抢完即止!
- SSD全能主机低至$2/月:含cPanel,性能与易用兼得!
- 亚太与欧盟优化专享 · 硅谷与密苏里DDoS防护 · 限时特惠36美元起
服务器评测



