per-CPU
变量顾名思义,即当你声明一个per-CPU
变量时,当前系统上的每个CPU
都会有一份当前变量的copy
。使用per-CPU
变量好处是访问它几乎不需要加锁,因为每个CPU
都有一份copy
。此外,CPU
可以把这个变量放在自己的cache
里,访问起来会特别快。定义per-CPU
变量方法如下:
DEFINE_PER_CPU(type, name);
如果per-CPU
变量是数组,则定义方式如下:
DEFINE_PER_CPU(type[length], array);
per-CPU
变量可以导出,供其它模块使用:
EXPORT_PER_CPU_SYMBOL(per_cpu_var);
EXPORT_PER_CPU_SYMBOL_GPL(per_cpu_var);
要在其它模块使用per-CPU
变量,则需要声明:
DECLARE_PER_CPU(type, name);
访问per-CPU
变量可以使用get_cpu_var(var)
和set_cpu_var(var)
这两个macro
:
/* <linux/percpu.h>*/
/*
* Must be an lvalue. Since @var must be a simple identifier,
* we force a syntax error here if it isn't.
*/
#define get_cpu_var(var) (*({ \
preempt_disable(); \
&__get_cpu_var(var); }))
/*
* The weird & is necessary because sparse considers (void)(var) to be
* a direct dereference of percpu variable (var).
*/
#define put_cpu_var(var) do { \
(void)&(var); \
preempt_enable(); \
} while (0)
因为kernel
线程是允许preemption
的,所以在get_cpu_var
中需要调用preempt_disable
,并且要和put_cpu_var
配对使用。
访问另一个CPU
的per-CPU
变量:
per_cpu(variable, int cpu_id);