mirror of
https://github.com/gatieme/LDD-LinuxDeviceDrivers.git
synced 2026-08-18 09:07:43 +08:00
description/scheduler: Revisiting the kernel's preemption model
This commit is contained in:
@@ -369,7 +369,7 @@ $reclaim = current\_mem \times reclaim\_ratio \times max(0,1 – \frac{psi_some}
|
||||
|
||||
| 时间 | 作者 | 特性 | 描述 | 是否合入主线 | 链接 |
|
||||
|:----:|:----:|:---:|:----:|:---------:|:----:|
|
||||
| 2009/03/25 | Peter Zijlstra <a.p.zijlstra@chello.nl> | [perf_counter: Add event overlow handling](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=43a21ea81a2400992561146327c4785ce7f7be38) | 使用 mmap() 提供更好的溢出管理和更可靠的数据流. 之前方法没有任何 user-> 内核反馈, 并依赖于用户空间保持更新, 与之不同的是,此方法依赖于用户空间将其最后一次读位置写入到控件页. 它将确保新输出不会覆盖尚未读取的事件, 同时允许丢失没有剩余空间的新事件, 并增加溢出计数器, 提供确切的事件丢失数字. 丢失事件用 PERF_EVENT_LOST(后来被改名为 [PERF_RECORD_LOST](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=cdd6c482c9ff9c55475ee7392ec8f672eddb7be6)) 标记. | v1 ☑✓ 2.6.31-rc1 | [LORE](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=43a21ea81a2400992561146327c4785ce7f7be38) |
|
||||
| 2009/03/25 | Peter Zijlstra <a.p.zijlstra@chello.nl> | [perf_counter: Add event overlow handling](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=43a21ea81a2400992561146327c4785ce7f7be38) | 使用 mmap() 提供更好的溢出管理和更可靠的数据流. 之前方法没有任何 user-> 内核反馈, 并依赖于用户空间保持更新, 与之不同的是, 此方法依赖于用户空间将其最后一次读位置写入到控件页. 它将确保新输出不会覆盖尚未读取的事件, 同时允许丢失没有剩余空间的新事件, 并增加溢出计数器, 提供确切的事件丢失数字. 丢失事件用 PERF_EVENT_LOST(后来被改名为 [PERF_RECORD_LOST](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=cdd6c482c9ff9c55475ee7392ec8f672eddb7be6)) 标记. | v1 ☑✓ 2.6.31-rc1 | [LORE](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=43a21ea81a2400992561146327c4785ce7f7be38) |
|
||||
| 2015/05/10 | Kan Liang <kan.liang@intel.com> | [large PEBS interrupt threshold](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/log/?id=c4937a91ea56b546234b0608a413ebad90536d26) | 其中 [perf/x86/intel: Introduce PERF_RECORD_LOST_SAMPLES](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=f38b0dbb491a6987e198aa6b428db8692a6480f8) 引入 PERF_RECORD_LOST_SAMPLES. | v9 ☑✓ 4.2-rc1 | [LORE v9,0/8](https://lore.kernel.org/all/1431285195-14269-1-git-send-email-kan.liang@intel.com) |
|
||||
| 2011/01/29 | Arnaldo Carvalho de Melo <acme@redhat.com> | [perf top: Switch to non overwrite mode](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=93fc64f14472ae24fd640bf3834a178f59142842) | perf top 发现 PERF_RECORD_LOST 丢失事件时上报 WARN. | v1 ☑✓ 2.6.39-rc1 | [LORE](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=93fc64f14472ae24fd640bf3834a178f59142842) |
|
||||
| 2011/10/29 | Arnaldo Carvalho de Melo <acme@redhat.com> | [perf hists browser: Warn about lost events](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=7b27509fc62686c53e9301560034e6b0b001174d) | 发现 PERF_RECORD_LOST 丢失事件时上报 WARN. | v1 ☑✓ 3.2-rc1 | [LORE](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=7b27509fc62686c53e9301560034e6b0b001174d) |
|
||||
@@ -399,9 +399,9 @@ $reclaim = current\_mem \times reclaim\_ratio \times max(0,1 – \frac{psi_some}
|
||||
## 11.3 Userspace counter access
|
||||
-------
|
||||
|
||||
x86 和 arm64 都支持直接访问用户空间中的事件计数器. 访问序列并不简单,目前存在于 perf 测试代码(tools/perf/arch/x86/tests/rdpmc.c)中, 在 PAPI 和 libpfm4 等项目中有类似的用例程序.
|
||||
x86 和 arm64 都支持直接访问用户空间中的事件计数器. 访问序列并不简单, 目前存在于 perf 测试代码(tools/perf/arch/x86/tests/rdpmc.c)中, 在 PAPI 和 libpfm4 等项目中有类似的用例程序.
|
||||
|
||||
为了支持 usersapce 访问,必须首先使用 perf_evsel__mmap() 映射事件. 然后, 对 perf_evsel__read() 对 PMU 进行读取.
|
||||
为了支持 usersapce 访问, 必须首先使用 perf_evsel__mmap() 映射事件. 然后, 对 perf_evsel__read() 对 PMU 进行读取.
|
||||
|
||||
|
||||
| 时间 | 作者 | 特性 | 描述 | 是否合入主线 | 链接 |
|
||||
@@ -768,6 +768,16 @@ Intel 编译器随后也切到 LLVM 框架, 参见 [Intel Fully Embracing LLVM F
|
||||
| 2023/06/12 | Peter Zijlstra <peterz@infradead.org> | [Scope-based Resource Management](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/log/?id=7170509cadbb76e5fa7d7b090d2cbdb93d56a2de) | [Scope-based resource management for the kernel](https://lwn.net/Articles/934679) 以及 [Scope-Based Resource Management Infrastructure Merged For Linux 6.5](https://www.phoronix.com/news/Linux-6.5-Scope-Resource-Manage). | v3 ☐☑✓ 6.6-rc1 | [LORE v3,0/57](https://lore.kernel.org/all/20230612090713.652690195@infradead.org) |
|
||||
|
||||
|
||||
## 13.14 Compiler
|
||||
-------
|
||||
|
||||
|
||||
| 编号 | 应用 | 功能 |
|
||||
|:---:|:----:|:---:|
|
||||
| 1 | [Cling](https://github.com/vgvassilev/cling) | 用于这个基于 LLVM/Clang 构建的开源交互式 C++ 解释器. Cling 是作为 LLVM/Clang 的扩展实现的, 以用作利用读取-求值-打印循环 (REPL) 概念的中间人, 并依赖于实时 (JIT) 编译. [Cling 1.0 发布用于交互式 C++ 解释器](https://www.phoronix.com/news/Cling-1.0-Released) |
|
||||
|
||||
|
||||
|
||||
# 14 FTRACE
|
||||
-------
|
||||
|
||||
@@ -908,7 +918,7 @@ User Events 于 [5.18-rc1](https://kernelnewbies.org/Linux_5.18#User_events) 合
|
||||
-------
|
||||
|
||||
|
||||
谷歌的Android因其移动操作系统以及各种供应商/设备内核树所携带的所有下游补丁而臭名昭著, 而近年来, 更多的代码已经上游. 谷歌也一直在转向Android通用内核映像(GKI)作为其所有产品内核的基础, 以进一步减少碎片化. 展望未来, 谷歌在 2021 年北美开源峰会展示了一种["上游优先"(Moving Google toward the mainline)](https://lwn.net/Articles/871195)的方法, 以推动新的内核功能. 追求"新功能的上游优先开发模型", 以确保新代码首先进入主线Linux内核, 而不是直接在Android源代码树中停留.
|
||||
谷歌的Android因其移动操作系统以及各种供应商/设备内核树所携带的所有下游补丁而臭名昭著, 而近年来, 更多的代码已经上游. 谷歌也一直在转向Android通用内核映像(GKI)作为其所有产品内核的基础, 以进一步减少碎片化. 展望未来, 谷歌在 2021 年北美开源峰会展示了一种["上游优先"(Moving Google toward the mainline)](https://lwn.net/Articles/871195)的方法, 以推动新的内核功能. 追求"新功能的上游优先开发模型", 以确保新代码首先进入主线Linux内核, 而不是直接在Android源代码树中停留.
|
||||
|
||||
谷歌的 Todd Kjos 随后在 Linux Plumbers Conference(LPC2021) 上谈到了他们的[通用内核映像(Generic Kernel Image, GKI)计划](https://linuxplumbersconf.org/event/11/contributions/1046). 通过 Android 12 和他们基于 Linux 5.10 的 GKI 映像, 进一步减少了碎片化, 以至于"几乎被消除". 在 Android 12 GKI 中, 大多数供应商/OEM 内核功能现在要么被上游到 Linux 内核中, 要么被隔离到供应商模块或者钩子中, 要么合并到 Android Common Kernel 中.
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -4900,6 +4900,7 @@ Energy Model Framework 统一了系统中所有能效的感知模块和设备,
|
||||
|
||||
DTB 中通过 OPP 字段标记 CPU 的电压及频率信息, 参见 [Documentation/devicetree/bindings/opp](https://www.kernel.org/doc/Documentation/devicetree/bindings/opp). 通过 CPUS 记录 CPU 的拓扑以及 capacity, 电容系数等信息, 参见 [Documentation/devicetree/bindings/arm/cpu-capacity](https://www.kernel.org/doc/Documentation/devicetree/bindings/arm/cpu-capacity.txt), 以及 [Documentation/devicetree/bindings/arm/cpus](https://www.kernel.org/doc/Documentation/devicetree/bindings/arm/cpus.yaml).
|
||||
|
||||
CPU 的 capacity 通过 capacity-dmips-mhz 来标记. CPU 的 power Energy Model 则提供了两种方式来注册, 一种是通过 dynamic-power-coefficient, 再结合电压和频率进行计算, 一种是不提供 dynamic-power-coefficient, 那么就要求在 OPP 表中通过 opp-microwatt 显式设置功耗数据.
|
||||
|
||||
| DTB 结构 | DTB 字段 | 描述 |
|
||||
|:-------:|:--------:|:---:|
|
||||
@@ -4910,6 +4911,9 @@ DTB 中通过 OPP 字段标记 CPU 的电压及频率信息, 参见 [Documentati
|
||||
|---------|----------|-----|
|
||||
| opp_table | opp-hz | CPU 频点 |
|
||||
| opp_table | opp-microvolt | CPU 对应频点下, 所需要的电压 |
|
||||
| opp_table | opp-microamp | CPU 对应频点下, 所需要的电流 |
|
||||
| opp_table | opp-microwatt | CPU 对应频点下, 所消耗的功耗 |
|
||||
|
||||
|
||||
v4.5 实现 [Dynamic power model from device tree](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/log/?id=2f7e8a175db72bdaf377235962fd85796edb3fbc) 时扩展了 CPU DTS 节点, 引入了 dynamic-power-coefficient 字段用来表示动态功率系数 (即电容系数), 从而有效地估计功耗.
|
||||
|
||||
@@ -5438,18 +5442,61 @@ CONFIG_SCHED_CORE_CTL 的方案, 不光通过 do_isolation_work_cpu_stop() 支
|
||||
## 8.1 抢占支持 (preemption)
|
||||
-------
|
||||
|
||||
**2.6 时代开始支持 ** (首次在 2.5.4 版本引入 [<sup>37</sup>](#refer-anchor-37), 感谢知友 [@costa](https://www.zhihu.com/people/78ceb98e7947731dc06063f682cf9640) 考证! 关于 Linux 版本规则, 可看我文章 [<sup>4</sup>](#refer-anchor-4).
|
||||
** 2.6 时代开始支持 ** (首次在 2.5.4 版本引入 [<sup>37</sup>](#refer-anchor-37), 感谢知友 [@costa](https://www.zhihu.com/people/78ceb98e7947731dc06063f682cf9640)
|
||||
|
||||
考证! 关于 Linux 版本规则, 可看我文章 [<sup>4</sup>](#refer-anchor-4).
|
||||
|
||||
|
||||
可抢占性, 对一个系统的调度延时具有重要意义. 2.6 之前, 一个进程进入内核态后, 别的进程无法抢占, 只能等其完成或退出内核态时才能抢占, 这带来严重的延时问题, 2.6 开始支持内核态抢占.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
| 时间 | 作者 | 特性 | 描述 | 是否合入主线 | 链接 |
|
||||
|:----:|:----:|:---:|:---:|:----------:|:----:|
|
||||
| 2021/01/18 | Frederic Weisbecker & Peter Zijlstra 等 | [preempt: Tune preemption flavour on boot v4](https://lore.kernel.org/patchwork/cover/1366962) | 增加了 PREEMPT_DYNAMIC 配置选项, 允许内核启动阶段选择使用哪种抢占模式 (none, voluntary, full) 等, 同时支持 debugfs 中提供开关, 在系统运行过程中动态的修改这个配置. | RFC v4 ☑ 5.12-rc1 | [PatchWork](https://lkml.org/lkml/2021/1/18/672), [LORE](https://lore.kernel.org/all/20210118141223.123667-1-frederic@kernel.org) |
|
||||
| 2021/10/25 | Frederic Weisbecker <frederic@kernel.org> | [arm64: Support dynamic preemption v2](https://lore.kernel.org/patchwork/cover/1366962) | 增加了 PREEMPT_DYNAMIC 配置选项, 允许内核启动阶段选择使用哪种抢占模式 (none, voluntary, full) 等, 同时支持 debugfs 中提供开关, 在系统运行过程中动态的修改这个配置. | RFC v4 ☑ 5.12-rc1 | [PatchWork](https://lkml.org/lkml/2021/10/25/500) |
|
||||
| 2023/11/07 | Ankur Arora <ankur.a.arora@oracle.com> | [Make the kernel preemptible](https://lore.kernel.org/all/20231107215742.363031-1-ankur.a.arora@oracle.com) | TODO | v1 ☐☑✓ | [LORE v1,0/86](https://lore.kernel.org/all/20231107215742.363031-1-ankur.a.arora@oracle.com) |
|
||||
|
||||
|
||||
| 日期 | LWN | 翻译 |
|
||||
|:---:|:----:|:---:|
|
||||
| 2023/09/21 | [Revisiting the kernel's preemption models (part 1)](https://lwn.net/Articles/944686) | [LWN:重新审视内核的多种抢占模型!](https://blog.csdn.net/Linux_Everything/article/details/133781615) |
|
||||
| 2023/10/02 | [Revisiting the kernel's preemption model, part 2](https://lwn.net/Articles/945422) | [LWN:重新审视内核抢占模型,第二部分!](https://blog.csdn.net/Linux_Everything/article/details/133820074)
|
||||
|
||||
|
||||
| 调度时机/抢占模式 | 返回用户态 | 显式抢占点(cond_resched()及其同类) | 返回内核(tick/IPI/irq at irqexit) | 不可抢占段在(preempt_count() == preempt_offset)处结束 |
|
||||
|:---:|:----:|:----:|:----:|:----:|
|
||||
| none(PREEMPT_NONE) | Y | N | N | N |
|
||||
| voluntary(CONFIG_PREEMPT_VOLUNTARY) | Y | Y | N | N |
|
||||
| full(CONFIG_PREEMPTION) | Y | N | Y | Y |
|
||||
| rt(CONFIG_PREEMPT_RT) | Y | N | Y | Y |
|
||||
|
||||
|
||||
由于没有明确的抢占点的理想位置, 它们往往随机分布在代码中, 并随着时间的推移而积累, 因为它们是在发现延迟问题时添加的.
|
||||
|
||||
在自愿模式中, 调度器的工作是匹配需求一侧的抢占点(需要安排的任务) 和供给端 (一个调用 cond_resched() 的任务). 而完全抢占模型跟踪抢占计数, 因此调度器可以始终知道抢占是否安全, 并且可以驱动抢占本身.
|
||||
|
||||
因此 Thomas 在 [Re: sched: define TIF_ALLOW_RESCHED](https://lore.kernel.org/lkml/87jzshhexi.ffs@tglx) 中概述的那样, 建议统一抢占模型, 并且希望: 始终启用 preempt_count 并允许调度程序驱动基于有效模型的抢占策略.
|
||||
|
||||
要做到这一点, 添加一个新的标志, TIF_NEED_RESCHED_LAZY 调度器来标记需要重新调度, 但被推迟到任务在内核中完成执行——自愿抢占. 原来的 TIF_NEED_RESCHED 标志仍然在所有三个抢占时计算点, TIF_NEED_RESCHED_LAZY 只需要在 ret-to-user 时判断.
|
||||
|
||||
| 调度时机/抢占模式 | ret-to-user | ret-to-kernel | preempt_count() |
|
||||
|:---:|:----:|:----:|:----:|
|
||||
| none | Y | N | N |
|
||||
| voluntary | Y | Y | Y |
|
||||
| full | Y | Y | Y |
|
||||
|
||||
这种是线下没有明确的抢占点了, 在内核中分布很长时间的进程就没有办法放弃 CPU. 对于完全抢占, 这是没有问题的, 因为我们总是使用 TIF_NEED_RESCHED. 对于无/自愿抢占, 如果标记为 TIF_NEED_RESCHED_LAZY 的任务在下一个 tick 之前没有抢占, 我们通过升级到 TIF_NEED_RESCHED 来处理它. 这样当任务 ret-to-kernel 时, 或者退出一个不可抢占的临界区时, 就触发抢占. 也就是说, 这提供了更一致的最大延迟 (~2 tick) 长度 + 不可抢占部分的长度) 与旧模型相比其中最大延迟取决于的动态分布 cond_resched() 点.
|
||||
|
||||
|
||||
| 时间 | 作者 | 特性 | 描述 | 是否合入主线 | 链接 |
|
||||
|:---:|:----:|:---:|:----:|:---------:|:----:|
|
||||
| 2023/11/07 | Ankur Arora <ankur.a.arora@oracle.com> | [Make the kernel preemptible](https://lore.kernel.org/all/20231107215742.363031-1-ankur.a.arora@oracle.com) | [New Set Of 86 Patches Overhaul The Linux Kernel's Preemption Model](https://www.phoronix.com/news/Overhaul-Linux-Preemptible-RFC) | v1 ☐☑✓ | [LORE v1,0/86](https://lore.kernel.org/all/20231107215742.363031-1-ankur.a.arora@oracle.com) |
|
||||
|
||||
|
||||
## 8.2 NO_HZ
|
||||
-------
|
||||
|
||||
@@ -594,4 +594,14 @@ BPF verifiery 已经做了很多工作来尽量确保加载进 kernel 的 BPF pr
|
||||
|
||||
在目前的情况下, 我们应该看到从 perf-script、perf-schedule-timehist 和 tp_printk 中报告的调度任务状态的三种不同结果. tracepoint sched_switch 的. 不难看出前两个是建立在第三个的基础上的, 这也是我们看到这个的原因. 不一致性在于前两种方法不能跟上随着内核发展而报告的任务状态定义的内部变化. 在 tracepoint sched_switch 中导出任务状态的内部表示并不是一个好的做法, 而且根本不鼓励这样做容易破坏依赖于它的用户空间工具. 特别是当跟踪点由于其稳定性而被大量应用于许多可观测性工具中时性质, 这使得它们不再仅用于调试目的, 我们应该小心地决定应该向用户空间报告什么, 以及什么不应该.
|
||||
|
||||
因此, 要彻底解决上面提到的问题, 而不是选择与用户空间跟踪工具同步
|
||||
因此, 要彻底解决上面提到的问题, 而不是选择与用户空间跟踪工具同步
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
| 日期 | LWN | 翻译 |
|
||||
|:---:|:----:|:---:|
|
||||
| 2023/09/21 | [Revisiting the kernel's preemption models (part 1)](https://lwn.net/Articles/944686) | [LWN:重新审视内核的多种抢占模型!](https://blog.csdn.net/Linux_Everything/article/details/133781615) |
|
||||
| 2023/10/02 | [Revisiting the kernel's preemption model, part 2](https://lwn.net/Articles/945422) | [LWN:重新审视内核抢占模型,第二部分!](https://blog.csdn.net/Linux_Everything/article/details/133820074)
|
||||
Reference in New Issue
Block a user