【问题标题】:How to execute a piece of kernel code on all CPUs?如何在所有 CPU 上执行一段内核代码?
【发布时间】:2016-04-10 13:42:48
【问题描述】:

我正在尝试制作一个内核模块来为 x87 FPU 启用 FOP 兼容模式。这是通过设置IA32_MISC_ENABLE MSR 中的第 2 位来完成的。代码如下:

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <asm/msr-index.h>
#include <asm/msr.h>

MODULE_LICENSE("GPL");
MODULE_AUTHOR("10110111");
MODULE_DESCRIPTION("Module to enable FOPcode compatibility mode");
MODULE_VERSION("0.1");

static int __init fopCompat_init(void)
{
   unsigned long long misc_enable=native_read_msr(MSR_IA32_MISC_ENABLE);
   printk(KERN_INFO "Before trying to set FOP_COMPAT, IA32_MISC_ENABLE=%llx,"
                    " i.e. FOP_COMPAT is %senabled\n"
                    ,misc_enable,misc_enable&MSR_IA32_MISC_ENABLE_X87_COMPAT?"":"NOT ");

   wrmsrl(MSR_IA32_MISC_ENABLE,misc_enable|MSR_IA32_MISC_ENABLE_X87_COMPAT);
   misc_enable=native_read_msr(MSR_IA32_MISC_ENABLE);

   printk(KERN_INFO "Tried to set FOP_COMPAT. Result: IA32_MISC_ENABLE=%llx,"
                    " i.e. FOP_COMPAT is now %senabled\n"
                    ,misc_enable,misc_enable&MSR_IA32_MISC_ENABLE_X87_COMPAT?"":"NOT ");
   return 0;
}

static void __exit fopCompat_exit(void)
{
   const unsigned long long misc_enable=native_read_msr(MSR_IA32_MISC_ENABLE);
   printk(KERN_INFO "Quitting FOP-compat with IA32_MISC_ENABLE=%llx\n",misc_enable);
   if(!(misc_enable & MSR_IA32_MISC_ENABLE_X87_COMPAT))
       printk(KERN_INFO "NOTE: seems some CPUs still have to be set up, "
                        "or compatibility mode will work inconsistently\n");
   printk(KERN_INFO "\n");
}

module_init(fopCompat_init);
module_exit(fopCompat_exit);

它似乎有效,但在多个insmod/rmmod 循环中,我有时会得到dmesg 输出,表明兼容模式仍未启用,尽管它是在执行wrmsr 之后立即启用的。经过一番思考,我意识到这是因为模块代码是在不同的逻辑 CPU 上执行的(我有 Core i7 和 4 核 *HT=8 逻辑 CPU),所以我有 1/8 的机会在做 @ 时获得“启用”打印987654326@。在重复循环大约 20 次后,我得到了一致的“启用”打印,并且我的用户空间应用程序很高兴地使用它。

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

【问题讨论】:

    标签: linux-kernel multiprocessing msr


    【解决方案1】:

    要在每个 CPU 上执行代码,请使用 on_each_cpu 函数。

    签名:

    int on_each_cpu(void (*func) (void *info), void *info, int wait)
    

    说明:

    在所有处理器上调用一个函数。

    如果wait 参数不为零,则在所有 CPU 上等待函数完成。

    函数func 不应该休眠,但整个on_each_cpu() 调用不应该在原子上下文中完成。

    【讨论】:

    • 什么时候可以使用有限制吗?意味着在内核初始化中的哪个点,在哪个函数运行之后和之前?
    • 我不太清楚。我想,内核线程子系统初始化后,函数就可以使用了。
    • 我面临一个奇怪的问题,即函数 on 出于某种原因在 cpu0 上运行,有什么想法吗?
    • 我不知道。您可以创建新的问题帖子,并在其中提供问题描述。
    • 可能是所有cpu都没有上线。见stackoverflow.com/questions/17456812/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-02-21
    • 2015-02-25
    • 2023-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多