【问题标题】:Mac OS X Kernel Extension CPU SelectionMac OS X 内核扩展 CPU 选择
【发布时间】:2013-05-09 20:19:03
【问题描述】:

我正在阅读英特尔性能计数器监视器 (http://software.intel.com/en-us/articles/intel-performance-counter-monitor-a-better-way-to-measure-cpu-utilization) 附带的特定于型号的寄存器 (MSR) 驱动程序内核扩展的源代码。由于 MSR/性能计数器的独立副本存储在不同的 CPU 上,因此有必要指定从哪个 CPU 读取。这是通过调用 mp_rendezvous_no_intrs 函数来完成的。

mp_rendezvous_no_intrs(cpuReadMSR, (void*)idatas);

这会导致每个处理器检查它是否是正确的处理器编号,如果是,则从 MSR 读取数据:

void cpuReadMSR(void* pIData){
    pcm_msr_data_t* data = (pcm_msr_data_t*)pIData;
    volatile uint cpu = cpu_number();
    if(data->cpu_num == cpu)
    {
        data->value = RDMSR(data->msr_num);
    }
}

我的问题是:关闭中断(通过 mp_rendezvous_no_intrs 完成)是否足以导致运行 cpuReadMSR 函数的线程始终保持在同一个 CPU 上?如果不是,我担心以下失败场景:

  1. cpu 使用 cpu_number() 读取其数字 id,确定它是正确的 CPU,并开始读取 MSR。
  2. 线程被调度程序抢占并移动到不同的 CPU。
  3. 已读取 MSR,但现在从不同的 CPU 读取,因此给出了错误的值。

【问题讨论】:

    标签: kernel kernel-module mach


    【解决方案1】:

    禁用中断会禁用所有中断,而不仅仅是其中一些。这包括定时器中断,它通常允许正在运行的线程被抢占。

    虽然中断被禁用,但没有任何东西(除了 CPU 异常之类的疯狂事件)可以中断您的代码在单个 CPU 上从头到尾运行。

    【讨论】:

    • 这几天有点理论...因为普通的中断路由/屏蔽子系统([IO]APIC)可以通过编程来创建any x86 陷阱(特别选择的那个词……256个中断向量中的任何一个,其中32个是陷阱,其中一个明确命名为NMI - 不可屏蔽中断)。在 CPU 级别禁用中断(cli 指令)不会关闭陷阱,因此不会禁用对 32 个较低编号的中断向量的硬件中断调度,如果 IOAPIC 配置为这样的话。简而言之:现在很难在 x86 CPU 上“禁用中断”。
    • 澄清一点......操作系统需要帮助您完成“在不会发生中断的情况下运行此代码 [在所有 cpus 上]”的任务。这是因为这样做需要复杂的设置 - 对 APIC 进行编程以阻止中断以及在没有处理器间中断的情况下进行 CPU 会合,以及屏蔽所有可能的 NMI 来源。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-10
    • 2018-11-12
    • 2015-04-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多