关注了就能看到更多这么棒的文章哦~
By *Daroc Alden*, January 13, 2026
Gemini translation
https://lwn.net/Articles/1051982/
Linux Plumbers Conference (LPC)
服务质量(Quality-of-Service,简称 QoS)机制尝试将某些进程(或网络流量、磁盘 I/O 等)的优先级提高到其他进程之上,以满足系统的性能目标。在 Linux 世界中,这是一个难以处理的话题,因为其工作负载、硬件和用户预期差异巨大。在 2025 年的 Linux Plumbers Conference (LPC) 上,Qais Yousef 与其合作者 John Stultz、Steven Rostedt 和 Vincent Guittot 共同介绍了他们计划如何为 Linux 引入一种高层级的 QoS API,并确保终端用户能够控制其配置。此次演讲专门针对调度器 (scheduler) 的 QoS 机制,旨在为不同类型的进程提供不同的 CPU 资源访问优先级。(幻灯片;视频)
Yousef 表示,从历史上看,服务器市场一直是优化 Linux 调度器性能的重要因素。虽然随着时间的推移这种情况有所改变,但至少在最初,调度器是极其注重吞吐量 (throughput) 的。近年来,人们开始更多地关注交互性 (interactivity),但在如何从 Linux 系统中压榨出最佳性能方面,仍然存在许多陈旧的假设。POSIX 尚未演进到足以涵盖这些新进展,应用程序仍然经常按照每个 CPU 核心生成一个线程,仿佛系统中没有运行其他工作负载一样。
内核中当前的默认调度器 EEVDF 拥有许多可配置参数,可以针对整个系统或每个进程进行调整。Yousef 认为,在 Linux 中实现 QoS API 的最佳方式是向调度器提供足够的进程信息,以便为现有的配置选项设置合理的默认值。他指出,过去人们一直关注与调度器通信的内核接口,但那并不是核心问题所在。真正重要的是为应用程序提供一个高层级的 API,使其在使用时不需要对调度器的配置有深入的了解。

iOS(以及相关的 macOS 和 watchOS 等平台)已经拥有了类似的接口。它提供了四个 QoS 级别供程序选择:用户交互(user interactive,用于更新程序界面的任务)、用户发起(user initiated,用于用户正在进行的操作)、实用工具(utility,用于应及时发生但不会直接影响用户的任务)以及后台(background,用于对延迟没有特殊要求的任务)。程序中的每个线程都可以独立设置 QoS 级别。
Yousef 提议将这一设计借鉴到 Linux 中,并将这些类别分别映射到调度器的时间片 (time slice)、策略 (policy)、升频乘数 (ramp-up multiplier) 和 uclamp 设置。线程将默认属于实用工具类,这与调度器当前的默认值相匹配。处于用户交互或用户发起类的线程将被分配更短的时间片,这告诉调度器应优先考虑延迟而非吞吐量。处于后台类的线程将被分配更长的时间片,以便在系统空闲时能够长时间运行而不受干扰,但如果有更高优先级的线程变为可运行状态,它们就会被中断。
一位现场观众提出反对意见,称 Linux 已经有一种控制不同线程分配时间的方法:deadline 调度器 (deadline scheduler)。Rostedt 随即插话问道:“大家真的想在 deadline 调度器下运行 Chrome 吗?”他澄清说,使用 deadline 调度器需要 root 权限,而 Yousef 的提案旨在允许普通的、非特权的应用程序提供性能暗示。这引发了观众席上关于 deadline 调度与性能暗示的长时间争论,直到 Yousef 将话题拉回正轨。
他表示,在调度器中采用 QoS 类别还需要对处理任务分配到不同 CPU 的代码进行一些更改。Guittot 解释说,目前内核根据四个标准之一来决定哪个 CPU 应该运行任务:CPU 负载、CPU 负载和能效、CPU 负载和 NUMA 域 (NUMA domain),或者核心亲和性 (core affinity)。这实际上应该扩展到考虑被放置任务本身的特性。当负载均衡器 (load balancer) 放置一个带有短时间片的任务时,它应该首先考虑空闲 CPU(任务可以在那里立即运行),但如果没有空闲 CPU,它应该优先将任务放在正在处理长时间片任务的 CPU 上(以便该任务可以被抢占)。
不过 Yousef 声称,内核中所需的代码更改并不是主要问题。问题在于如何鼓励应用程序开发者采用新的 API;人们往往需要数年时间才会真正开始使用新的内核 API。他说:“我认为我们可以做得更好。”与其使用基于在代码中调用函数的接口(这要求应用程序开发者更新程序以将其考虑在内),为什么不使用基于配置文件的方法呢?这样,如果应用程序愿意,可以随附默认配置文件,而用户和发行版维护者也可以为任何希望支持新 API 的应用程序添加配置文件。这也让系统的用户拥有了最终控制权:如果应用程序提供了一个糟糕的默认配置,用户可以覆盖它。
有人问,为什么应用程序开发者不直接提供一个将所有线程都设为最高优先级的配置。另一位观众指出,提议的 QoS API 实际上对单个应用程序内部的线程优先级排序最有用;例如,一款视频游戏会希望将用户界面部分设为用户交互类,但如果将后台清理任务也设为同一类别,只会导致抖动或延迟,同时还会降低后台处理的吞吐量。
Yousef 还表示,内核不应被迫无论如何都盲目遵循应用程序的配置。应该有适当的访问控制。如果应用程序请求用户交互 QoS 类别,但系统知道该程序当前并不在前端运行(可能是由于来自桌面环境的提示、控制组的使用或某些其他进程管理机制),系统可以将其限制在实用工具类。另一方面,任何应用程序都应该被允许将线程标记为后台类,以获得吞吐量优势,因为这些线程不会影响延迟。
Yousef 总结道,重点是向调度器提供更多信息,以便其针对不同的工作负载做出合理的决策。对于主要关注吞吐量的服务器,将所有内容保持在默认 QoS 级别并让现有代码(大部分已经针对服务器进行了优化)来处理是有意义的。而对于笔记本电脑、手机以及其他延迟比纯吞吐量更重要的应用场景,向调度器指明少数最重要的线程能让它做出更好的决策。
他补充说,内核中还有其他正在进行的工作也将对此有所帮助。会议的工具链轨道 (toolchains track) 讨论了如何允许高优先级任务将 CPU 时间(或者可能是其他资源,如 QoS 类别或其他调度器设置)“捐赠”给当前持有高优先级任务所需锁的低优先级任务。这样,高优先级任务就不会因为等待低优先级任务被调度到 CPU 上而陷入停滞(这种情况被称为优先级反转,priority inversion)。这类工作在历史上被称为优先级继承 (priority inheritance),但在工具链轨道的演讲中被称为性能继承 (performance inheritance),以表明它涉及的不只是优先级。Yousef 表示,无论称呼如何,这项工作都将有助于改善用户可见的延迟。
Linux 最终是否会采用 QoS API,以及它是否会如此紧密地模仿 Apple 的 API 所提供的一套机制,仍有待观察。显然,近年来内核调度子系统已经发生了转变,开始越来越多地关注吞吐量以外的问题。如果这种趋势继续下去(目前看来很有可能),用户可以期待未来会有更具响应性的用户界面。
[ 感谢 Linux Foundation 资助我参加 Linux Plumbers Conference。 ]
LWN 评论概述
评论区对提案的公平性与响应性展开了深入讨论。有用户质疑为何要对批处理任务保持“公平”,认为系统应更激进地优先保障前端 UI 工作,而非仅仅缩短时间片以换取响应速度。针对资源限制,有人指出许多应用会忽略 cgroups 或亲和性设置,建议通过修改 /proc/cpuinfo 隐藏不可用 CPU 来强制约束应用。此外,用户对比了 Windows 和 Linux 的系统健壮性,强调即便在极端负载下,系统也应保留足够的 CPU 和内存资源用于鼠标移动和启动终端,以避免用户在遇到失控程序时只能强行重启。还有评论提醒道,内核中已存在 pm_qos 和 tc 等 QoS 框架,需注意功能重叠与集成。整体讨论反映了用户对 Linux 在移动和桌面端维持基本交互能力的迫切需求。
全文完LWN 文章遵循 CC BY-SA 4.0 许可协议。
欢迎分享、转载及基于现有协议再创作~
长按下面二维码关注,关注 LWN 深度文章以及开源社区的各种新近言论~
783



被折叠的 条评论
为什么被折叠?



