Linux 内核基本概念(一)----PerCPU变量

来源:互联网 发布:java 获取当前路径 编辑:程序博客网 时间:2024/06/03 06:00
 

linux SMP环境中,某些变量在CPU同时时,并不需要进行互斥操作,为了支持这种功能,引入了percpu变量的概念。

这些变量在每个CPU上有一个副本,它们相互没有影响,但是它们拥有相同的类型和名字。这样在编码的时候,只需要变量名称就可以访问,但是可能访问的是不同的拷贝,这由当前程序运行在哪个CPU决定的。

在实际使用中,首先都要获取当前CPU上的值,然后在操作改变量。

 

1.1           API

1.1.1       定义

#define DEFINE_PER_CPU(type, name)

上面的宏定义了一个percpu变量,实际上定义了一个类型为type,名称为per_cpu__##name的变量,它实际存放的位置为:

 

u      SMP.data.percpu section

u      CPU.data

 

1.1.2       使用

(1)   get_cpu_var(var)/ put_cpu_var(var)

当需要对某个percpu变量进行操作时,首先通过get_cpu_var(var)来获取当前cpu上的该变量的地址,并且同时preempt_disable,这样防止当前的执行体(进程、softirq等等)被切换到其它的CPU上。

当变量操作完毕,调用put_cpu_var(var),打开调度preempt_enable()

 

(2)   __get_cpu_var(var)

如果不需要关闭调度,可以直接使用该函数获取当前cpu上的该变量地址。

 

1.2           实现

main.càstart_kernel()àsetup_per_cpu_areas()函数中,将会根据cpu的数目,将.data.percpu 段中的数据,拷贝到为每个CPU分配的内存区间中。并且设置__per_cpu_offset的值,这样对每个cpu上的变量的访问,直接由该变量per_cpu_xxxxxxx的地址加上该偏移值,就可以获取在某个cpu上该变量的地址。如下图所示。