【问题标题】:FPU usage in Linux kernelLinux内核中的FPU使用
【发布时间】:2014-09-26 07:58:03
【问题描述】:

如果 Linux softirq 通过中断 Linux 内核模式运行,并且被中断的任务正在使用 FPU,则不允许在 softirq 中使用 FPU。

如果被中断的任务是用户态进程,它仍然可以在 softirq 中使用 FPU,但不能中断内核态。

讨论中的代码如下。

问题是,为什么会这样?

static inline bool interrupted_kernel_fpu_idle(void)
{
    return !__thread_has_fpu(current) &&
        (read_cr0() & X86_CR0_TS); 
}

【问题讨论】:

    标签: c linux assembly linux-kernel x86


    【解决方案1】:

    只有一个地方可以存储 FPU 状态。如果你中断的内核模式代码已经保存了用户模式的FPU状态,那么就没有地方保存被中断的内核模式的FPU状态了。

    【讨论】:

    • "只有一个地方可以存储 FPU 状态。"它保存在内核中的哪个位置?据我了解,它将保存在正在运行的进程的 task_struct 中。
    • 是的,它将在task_struct 中。这个答案更详细:stackoverflow.com/a/16068179
    • 谢谢。如果我们看到上面有问题的代码,“interrupted_kernel_fpu_idle”。该函数检查内核模式是否发生中断。在这种情况下,它预计中断的内核线程不使用 FPU。为什么会这样?内核线程也应该能够将fpu状态保存在task_struct中。
    • interrupted_kernel_fpu_idle 函数不检查是否在执行内核代码时发生中断。只有在执行用户模式代码时没有发生中断时才会调用此函数。
    • 对于想要使用 FPU 进行状态保存/恢复自身的中断例程 - 到当前运行的内核堆栈,这是可以想象的。这有几个问题(必须禁用嵌套中断和抢占,并且可能需要测试堆栈上是否有足够的空间可用,因为整个 FPU 上下文是几百字节,但内核堆栈非常小)。这样做的开销很大 - 从中​​受益的用例必须......有点特别。足够特别,以至于内核作者认为它不值得。
    猜你喜欢
    • 2017-04-08
    • 2012-12-02
    • 1970-01-01
    • 1970-01-01
    • 2015-09-25
    • 1970-01-01
    • 1970-01-01
    • 2017-09-19
    相关资源
    最近更新 更多