Linux kernel 如何在所有CPU上执行一段内核代码?

Linux kernel 如何在所有CPU上执行一段内核代码?,linux-kernel,multiprocessing,msr,Linux Kernel,Multiprocessing,Msr,我正在尝试制作一个内核模块,以便为x87 FPU启用FOP兼容模式。这是通过在IA32\u MISC\u ENABLEMSR中设置位2来实现的。代码如下: #包括 #包括 #包括 #包括 #包括 模块许可证(“GPL”); 模块作者(“10111”); 模块描述(“启用FOPcode兼容模式的模块”); 模块_版本(“0.1”); 静态int\uu init fopCompat\u init(void) { 无符号长-长杂项启用=本机读取msr(msr IA32杂项启用); printk(KER

我正在尝试制作一个内核模块,以便为x87 FPU启用FOP兼容模式。这是通过在
IA32\u MISC\u ENABLE
MSR中设置位2来实现的。代码如下:

#包括
#包括
#包括
#包括
#包括
模块许可证(“GPL”);
模块作者(“10111”);
模块描述(“启用FOPcode兼容模式的模块”);
模块_版本(“0.1”);
静态int\uu init fopCompat\u init(void)
{
无符号长-长杂项启用=本机读取msr(msr IA32杂项启用);
printk(KERN_INFO“在尝试设置FOP_COMPAT之前,IA32_MISC_ENABLE=%llx,”
“即FOP_COMPAT已%s启用\n”
,杂项启用,杂项启用&MSR_IA32_杂项启用_X87_兼容?“:“否”);
wrmsrl(MSR_IA32_其他启用,其他启用| MSR_IA32_其他启用| X87_兼容);
杂项启用=本机读取msr(msr\u IA32\u杂项启用);
printk(KERN_INFO“试图设置FOP_兼容。结果:IA32_MISC_ENABLE=%llx,”
“即FOP_COMPAT现在已%s启用\n”
,杂项启用,杂项启用&MSR_IA32_杂项启用_X87_兼容?“:“否”);
返回0;
}
静态无效退出fopCompat退出(无效)
{
const unsigned long long misc_enable=本机读取msr(msr IA32_misc_enable);
printk(KERN_INFO“退出与IA32_MISC_ENABLE=%llx\n的FOP兼容”,MISC_ENABLE);
如果(!(其他启用和MSR IA32其他启用X87兼容))
printk(KERN_INFO)“注意:似乎仍需要设置一些CPU,”
“或兼容模式将不一致地工作\n”);
printk(内核信息“\n”);
}
模块初始化(fopCompat初始化);
模块出口(fopCompat出口);
它似乎可以工作,但在多个
insmod/rmmod
周期中,我有时会得到
dmesg
输出,即兼容性模式仍然没有启用,尽管它是在执行
wrmsr
之后立即启用的。经过一番思考,我意识到这是因为模块代码是在不同的逻辑CPU上执行的(我有4个内核*HT=8个逻辑CPU的内核i7),所以我有1/8的机会在执行
rmmod
时得到“启用”打印。在重复这个循环大约20次后,我得到了一致的“启用”打印,我的用户空间应用程序很高兴地使用它


所以现在我的问题是:如何使我的代码在系统上的所有逻辑CPU上执行,以便为所有CPU启用兼容模式?

对于在每个CPU上执行代码,请在每个CPU上使用
函数

签名:

int on_each_cpu(void (*func) (void *info), void *info, int wait)
说明:

在所有处理器上调用函数

如果
wait
参数为非零,则它将在所有CPU上等待函数完成


函数
func
不应该休眠,但是每个cpu()上的整个
调用不应该在原子上下文中进行。

对于何时可以使用它有任何限制吗?这意味着在内核初始化的哪个点,在哪个函数运行之后和之前?我不太清楚。我想,在内核线程子系统初始化之后,这个函数就可以使用了。我面临一个奇怪的问题,因为某种原因,这个函数在cpu0上运行,有什么想法吗?我不知道。您可以创建新的问题帖子,并在其中提供问题的描述。可能是因为所有CPU尚未联机。看见