Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1567089
  • 博文数量: 77
  • 博客积分: 1205
  • 博客等级: 少尉
  • 技术积分: 4476
  • 用 户 组: 普通用户
  • 注册时间: 2010-04-22 21:48
文章分类
文章存档

2018年(1)

2017年(1)

2015年(1)

2014年(18)

2013年(12)

2012年(44)

分类: LINUX

2013-01-29 15:00:36

在SMP环境下,你当前的代码在同一时间点只可能运行在某一个处理器上,那么如何这段代码需要操作其他处理器上的寄存器,该如何做呢?举个简单的例子吧,假设我当前的系统中有4颗core (关于Socket, Processor, Core的区分此文不展开),如果我现在想写一段代码来初始化这4颗core上的PMU寄存器(每个core都有自己专属的registers),怎么操作?


其实内核的msr模块提供了借鉴的代码:


get_online_cpus();
for_each_online_cpu(i) {
        ...
}
put_online_cpus();

上面代码通过for_each_online_cpu来枚举系统中所有core的id值,也就是常说的cpuid. 在上面的例子中,cpuid=0,1,2,3.

有了cpuid,就可以通过rdmsr_safe_on_cpu(cpu...)和wrmsr_safe_on_cpu(cpu...)来操作每个core的寄存器。


那么rdmsr/wrmsr_safe_on_cpu()函数的背后原理是基于什么来获得各个cpu上的寄存器地址呢?答案简单地说就是APIC. 系统中每个cpu将由APIC识别并在系统初始化时将其寄存器base addr记录在一个per_cpu型的变量中,这样通过cpuid就可以获得每个处理器的register base addr.


阅读(3610) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~