在Linux设备驱动程序中使用浮点的编码约定是什么?

时间:2009-01-10 15:05:28

标签: linux floating-point linux-device-driver fxsave

这与此有关 this question

我不是Linux设备驱动程序或内核模块方面的专家,但我一直在阅读Rubini& amp;的“Linux设备驱动程序”[O'Reilly]。 Corbet和一些在线资源,但我还没有找到关于这个具体问题的任何内容。

何时允许内核或驱动程序模块使用浮点寄存器?
如果是,谁负责保存和恢复其内容?
(假设x86-64架构)

如果我理解正确,只要KM正在运行,它就会使用硬件上下文(或硬件线程或寄存器集 - 无论你想要什么),它已被某些应用程序线程抢占。如果用c编写KM,编译器将正确地确保通用寄存器被正确保存和恢复(就像在应用程序中一样),但浮点寄存器不会自动发生。就此而言,许多知识管理员甚至不能假设处理器具有任何浮点功能。

我是否正确地猜测想要使用浮点的KM必须小心保存并恢复浮点状态?这样做有标准的内核函数吗?

此处的编码约定是否在任何地方拼写?
它们对于SMP非SMP驱动程序是否不同?
对于较旧的非抢占式内核和较新的抢占式内核,它们是不同的吗?

2 个答案:

答案 0 :(得分:11)

Linus's answer提供了这个非常明确的引用作为指南:

  

换句话说:规则是你真的不应该在内核中使用FP。

答案 1 :(得分:8)

简短回答:如果此用途被kernel_fpu_begin() / kernel_fpu_end()包围,则内核代码可以使用浮点数。这些函数处理保存和恢复fpu上下文。此外,他们调用preempt_disable() / preempt_enable(),这意味着这些函数之间的代码中没有睡眠,页面错误等。谷歌的功能名称更多信息。

  

如果我理解正确,无论什么时候   KM正在运行,它正在使用硬件   上下文(或硬件线程或   注册集 - 无论你想要什么   叫它)已经被抢先一步   一些应用程序线程。

不,内核模块也可以在用户上下文中运行(例如,当用户空间调用KM提供的设备上的系统调用时)。但是,它与浮动问题无关。

  

如果你用c写你的KM,那么   编译器会正确地确保   通用寄存器是   妥善保存和恢复(就像   在一个应用程序中),但事实并非如此   自动发生   浮点寄存器。

这不是因为编译器,而是因为内核上下文切换代码。