不需要上下文切换的系统调用?

8
我正在阅读一本操作系统书籍,了解Linux的工作原理,然后我发现了这个内容。
引用如下:“[...]内核被创建为单个的、整体的二进制文件。主要原因是为了提高性能。因为所有内核代码和数据结构都保存在单个地址空间中,所以当进程调用操作系统函数或硬件中断被传递时,不需要进行上下文切换。”
对我来说,这听起来相当惊人,但它必须在运行到内核模式处理中断之前存储进程的上下文。但好吧,我暂且相信它。在几页之后,描述了一个进程的调度上下文:
引用如下:“该进程执行时发生的系统调用和中断都将使用此堆栈。”
“此堆栈”是内核存储进程寄存器等信息的地方。
这不是对第一条引用的直接矛盾吗?我是否误解了它?
3个回答

6

我认为第一句话是在指一个单体内核和一个微内核之间的区别。

Linux是单体内核,所有的内核组件(设备驱动程序、调度程序、虚拟内存管理器)都在ring 0运行。因此,在执行系统调用和处理中断时不需要进行上下文切换。

相比之下,微内核的组件如设备驱动程序和IPC提供者在user space中运行,而不是在ring 0中。因此,这种架构在执行系统调用(因为执行模块可能驻留在user space中)和处理中断(将中断传递给设备驱动程序)时需要额外的上下文切换。


谢谢。我已经很久没有学习这个了,但是我印象中硬件中断实际上会“中断”执行,并立即跳转到处理过程,而不是之后轮询中断。我想如果进程在内核模式下执行,它仍然需要在跳转之前保存上下文,但也许那是我的错误?我猜现在这与任何其他方法调用没有区别,只要被调用的方法正确处理使用的寄存器...我理解得对吗? - user1130005
我的理解是进程在用户模式下运行,在中断处理之前确实会发生上下文切换到内核模式。但是,在单片内核中处理中断不需要额外的上下文切换,而在微内核中需要(因为设备驱动程序驻留在用户空间)。 - Frédéric Hamidi
我很好奇为什么设备驱动程序不在内核模式下而是在用户空间中? - codexplorer

4
"上下文切换"可能意味着两件事情,都很相关:(1)从用户模式切换到内核模式以处理系统调用,或者在中断堆栈中处理中断时进行无意识的内核模式切换;(2)在用户空间中运行另一个用户进程,并在两个进程之间跳转到内核空间。
任何从用户空间到内核空间的移动都意味着保存足够的用户空间以可靠地返回。如果内核空间代码决定 - 虽然您不再运行该进程的用户代码 - 是时候让另一个用户进程运行了,那么就进入了内核空间。
因此,至少需要2-3个堆栈或位置来存储“上下文”:硬件中断需要内核级别的堆栈来说明要返回什么;用户方法/子例程调用使用标准堆栈来完成此操作。等等。
最初的Unix内核 - 对于这部分,模型现在并没有太大的区别 - 像短命令厨师一样处理系统调用:将其移动到火炉上以腾出空间,以处理刚到达的培根订单,开始煎培根,回到第一个订单。所有这些在内核切换上下文中进行。这不是一个巨大的监控应用程序,这可能让IBM和DEC的软件人员发疯。

1
在Linux中进行系统调用时,需要从用户空间切换到内核空间(ring3 到 ring0)进行上下文切换。每个进程都有一个关联的内核模式堆栈,该堆栈由系统调用使用。在执行系统调用之前,进程的CPU寄存器被存储在其用户模式堆栈上,该堆栈与内核模式堆栈不同,并且是进程用于用户空间执行的堆栈。
当进程处于内核模式(或用户模式)时,调用相同模式的函数不需要进行上下文切换。这是第一条引言所指的内容。
第二条引言涉及内核模式堆栈,而不是用户模式堆栈。
话虽如此,我必须提到 Linux 的优化,即在执行系统调用时不需要转换到内核空间,即所有与系统调用相关的处理都在用户空间自行完成(因此没有上下文切换)。 vsyscall 和 VDSO 就是这样的技术。它们背后的想法非常简单。它是将执行相应系统调用所需的数据发送到用户空间。更多信息可以在 this LWN article 中找到。
除此之外,还有一些研究项目,在这些项目中所有执行都在同一个环中进行。用户空间程序和操作系统代码都驻留在同一环中。其想法是摆脱环切换的开销。微软的[singularity][2]操作系统就是这样一个项目。

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