对per-cpu变量tvec_bases的疑问
///定义了一个per cpu变量.这里要知道定时器的注册和触发执行一定是在相同的cpu上的.struct tvec_base boot_tvec_bases;
static DEFINE_PER_CPU(struct tvec_base *, tvec_bases) = &boot_tvec_bases;
疑问:
tvec_bases虽然是per cpu变量,但是指向的都是&boot_tvec_bases,也就是说不同的cpu其实操作的都是同一个变量,这样做有什么意义呢?能避免同步问题么? 启动的时候,会将这个变量做一个偏移处理,实际上每个tvec_base指向的都是不同的值,只是要基于boot_tvec_bases这个变量去找本节点的变量,不知道说清楚没 回复 1# jinxinxin163
///定义了一个per cpu变量.这里要知道定时器的注册和触发执行一定是在相同的cpu上的.
struct tvec_base boot_tvec_bases;
static DEFINE_PER_CPU(struct tvec_base *, tvec_bases) = &boot_tvec_bases;
疑问:
tvec_bases虽然是per cpu变量,但是指向的都是&boot_tvec_bases,也就是说不同的cpu其实操作的都是同一个变量,这样做有什么意义呢?能避免同步问题么?
你是这么理解per_cpu的?
per_cpu的含义是同一个变量名,对应多个存储地址,当每个CPU访问的时候,根据CPUID便宜到相应的地址,所以不同的CPU访问同一个变量名,但实际上却是不同的物理地址。
回复 1# jinxinxin163
真的tvec_bases会在static int __cpuinit init_timers_cpu(int cpu)函数里进行重新赋值,这样,每个CPU的tvec_base就不一样了。boot_tvec_bases这个base,最终只会留给启动核来用。
static int __cpuinit init_timers_cpu(int cpu)
{
int j;
struct tvec_base *base;
static char __cpuinitdata tvec_base_done;
if (!tvec_base_done) {
static char boot_done;
if (boot_done) {
/*
* The APs use this path later in boot
*/
base = kmalloc_node(sizeof(*base),
GFP_KERNEL | __GFP_ZERO,
cpu_to_node(cpu));
《。。。》
per_cpu(tvec_bases, cpu) = base;
} else {
/*
* This is for the boot CPU - we use compile-time
* static initialisation because per-cpu memory isn't
* ready yet and because the memory allocators are not
* initialised either.
*/
boot_done = 1;
base = &boot_tvec_bases;
}
spin_lock_init(&base->lock);
tvec_base_done = 1;
} else {
base = per_cpu(tvec_bases, cpu);
}
《。。。》
} @瀚海书香@super皮波
我想两位可能理解错了楼主的意思了。
tvec_bases是PerCPU没错。会有多份物理地址不同,但变量名叫tvec_bases的也没错。但每一份的的副本里头的存内容是什么?楼主可以关心的是这个,关心的是这个核的这个PerCPU是不是都同时指向boot_tvec_bases。 这种问题,只要知道per-cpu变量是如何存放的就知道了,初始化的时候会拷贝n份(n是cpu的个数),在使用的时候,每个cpu节点使用自己的那份拷贝 回复 2# super皮波
那按照你的意思,其实把boot_tvec_bases赋值过去就好了,没必要是&boot_tvec_bases把
回复 3# 瀚海书香
感谢啊,这里我主要是对&boot_tvec_bases不太理解,我的理解是boot_tvec_bases就好了
既然,这里是指针,那么不同cpu都有一个指针指向&boot_tvec_bases,那么其实还是一个变量,对否?
事实不是,所以,我的理解肯定不对 回复 7# jinxinxin163
那按照你的意思,其实把boot_tvec_bases赋值过去就好了,没必要是&boot_tvec_bases把
tvec_bases是基于boot_tvec_bases的地址来去分配和查找当前cpu上的tvec_bases变量的
你直接找文档看看,per-cpu变量的分配和查找过程,看完了,你肯定就没有疑问了
页:
[1]