为什么Linux不使用通过TSS进行硬件上下文切换的方式?

43

我读到了以下陈述:

x86架构包括一种特定的段类型,称为任务状态段(TSS),用于存储硬件上下文。尽管Linux不使用硬件上下文切换,但它仍然被迫为系统中每个不同的CPU设置一个TSS。

我想知道:

  • 为什么Linux不使用硬件支持来进行上下文切换?
  • 硬件方法难道不比软件方法快得多吗?
  • 有没有操作系统利用硬件上下文切换呢?Windows是否使用它?

最后,也如往常一样,感谢您的耐心和回复。

-----------添加--------------

http://wiki.osdev.org/Context_Switching提供了一些解释。

和我一样困惑的人可以看一下。 8^)


1
我发誓我刚刚正在阅读OSDev论坛并读到了这个信息 ;) - Earlz
@Andy - 最后一个支持硬件任务切换的内核是2.1.108。 - Pedro
3个回答

48

x86 TSS在硬件多任务处理中非常缓慢,与软件任务切换相比几乎没有任何优势(实际上,我认为手动切换任务往往比TSS更胜一筹)。

TSS也因其烦人且繁琐而闻名,并且即使对于x86-64架构也不可移植。Linux旨在在多个架构上运行��因此他们可能选择使用软件任务切换,因为它可以以机器无关的方式编写。此外,软件任务切换提供了更多可以完成的操作并且通常比使用TSS更容易设置。

我认为Windows 3.1使用了TSS,但至少NT>5内核没有使用。我不知道有任何类Unix操作系统使用TSS。

请注意,TSS是强制性的。操作系统所做的事情是为每个处理器创建一个单独的TSS条目,并且每次需要切换任务时,它们只需更改此单个TSS。软件任务切换在TSS中仅使用ESP0SS0字段。这用于从Ring 3代码转到Ring 0的中断。没有TSS,就没有已知的Ring 0堆栈,这显然会导致GPF并最终三重错误。


谢谢Earlz。我将您的回答标记为答案。也感谢其他人。 :D - smwikipedia
2
基于 TSS 的交换提供了硬件级别的状态管理(即:安全性),而软件交换则没有。在 80 年代引入到 IA 中的 TSS 和特权系统都在保护进程之间发挥作用。因此,总结一下,“有些操作系统不使用基于硬件的任务切换,因为它们更注重性能和可移植性而非安全性。”听起来很合理。 - Shaun Wilson
1
顺便提一下,NT使用M:N线程模型,与“其他系统”不同,硬件和软件线程之间没有1:1的关系,这不仅解决了“任务切换性能问题”,而且还可以解决更多问题。并非所有系统都可以实现M:N模型(例如由于紧密耦合硬件线程到特定CPU和进程),因此尝试实现M:N模型会遭受性能惩罚(因为这样的系统缺乏适当的硬件=>用户模式信号机制,这也不会占用原始执行线程)。 - Shaun Wilson
1
@ShaunWilson 我对那个说法的准确性有疑问。当选择器被加载时,CPU会检查它们的权限。在x86_64上没有要检查的选择器权限。使用TSS到底可以获得什么“额外安全性”? - doug65536

20

据我所知,在 Linux 1.3 之前,Linux 曾使用基于硬件的切换方式。然而,后来发现基于软件的上下文切换更快,且更加灵活。

另一个原因可能是为了最小化架构相关代码。Linux 第一个移植到非 x86 架构的版本是 Alpha,而 Alpha 没有 TSS,如果所有架构都使用软件切换,则可以共享更多的代码(这只是一个猜测)。不幸的是,在 1.2-1.3 内核版本期间的变更日志并没有得到很好地保存,因此我无法给出更具体的信息。


感谢Andy提供的历史信息。 :D - smwikipedia

7

Linux不使用分段内存模型,因此这种分段特定的功能并没有被使用。

x86 CPU具有许多不同类型的硬件支持来进行上下文切换,所以区别不是硬件与软件之间,而更多地是操作系统如何使用各种可用的硬件功能。不必使用它们所有。

Linux非常注重效率,可以肯定的是有人已经对可能的每个选项进行了剖析,并且当前使用的选项是最好的可用折衷方案。


谢谢你,安德鲁。你能告诉我x86 CPU提供了哪些其他硬件支持上下文切换吗?我只听说过TSS。 - smwikipedia
大多数MMU功能只有在多线程环境中才有意义。例如,即使没有使用其他字段,CPU也会强制Linux使用TSS作为ESP寄存器。我想这里的软件任务切换部分应该有你需要的大部分指针:http://wiki.osdev.org/Task_State_Segment - Andrew McGregor
1
在Andrew的最后一条评论的基础上:TSS对于诸如ring3 -> ring0转换是必需的,它会获取ESP0值。这可以防止内核在进入ring0时使用ring3堆栈 - 这是一项安全功能。Linux为每个CPU使用一个TSS进行此转换。 - Matthew Iselin
谢谢Andrew和Matthew。我只能标记一个答案。你们的回答也很有启发性。:D - smwikipedia

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接