diff --git a/study/kernel/00-DESCRIPTION/SCHEDULER.md b/study/kernel/00-DESCRIPTION/SCHEDULER.md index 30a8b8b..c6edbba 100644 --- a/study/kernel/00-DESCRIPTION/SCHEDULER.md +++ b/study/kernel/00-DESCRIPTION/SCHEDULER.md @@ -445,7 +445,11 @@ RT_RUNTIME_SHARE 这个机制本身是为了解决不同 CPU 上, 以及不同 如果你有任务属于该类型, 可以用 **_sched\_setscheduler()_** 或 **_sched\_setattr()_** API 设置此策略. -更多可参看此文章: [Deadline scheduling: coming soon? [LWN.net]](https://link.zhihu.com/?target=https%3A//lwn.net/Articles/575497/) +更多可参看此文章: [Deadline scheduling: coming soon? [LWN.net]](https://link.zhihu.com/?target=https%3A//lwn.net/Articles/575497). + +| 时间 | 作者 | 特性 | 描述 | 是否合入主线 | 链接 | +|:----:|:----:|:---:|:----:|:---------:|:----:| +| 2023/06/08 | Daniel Bristot de Oliveira | [SCHED_DEADLINE server infrastructure](https://lore.kernel.org/all/cover.1686239016.git.bristot@kernel.org) | 如果具有较高优先级的任务(例如 SCHED_FIFO)独占 CPU, 则低优先级任务(例如, SCHED_OTHER)可能会出现饥饿. RT Throttling 是不久前引入的一种(主要是调试)对策, 可以用来为低优先级任务(通常是后台类型的工作, 例如工作队列、计时器等)保留一些 CPU 时间. 然而, 它也有自己的问题(请参阅文档), 并且即使不需要运行优先级较低的活动, 也会无条件地限制 FIFO 任务, 这会产生不希望的影响(也有一些机制可以解决这个问题, 但同样也有其自身的问题). 引入截止日期服务器, 为饥饿条件下的低优先级任务需求提供服务. 最后期限服务器是通过扩展 SCHED_Deadline 实现来构建的, 以允许两级调度(即, deadline 实体成为低优先级调度实体的容器). | v3 ☐☑✓ | [LORE v1,00/13](https://lore.kernel.org/all/20190726145409.947503076@infradead.org)
*-*-*-*-*-*-*-*
[LORE v2,0/6](https://lore.kernel.org/all/20200807095051.385985-1-juri.lelli@redhat.com)
*-*-*-*-*-*-*-*
[LORE v3,0/6](https://lore.kernel.org/all/cover.1686239016.git.bristot@kernel.org) | ## 1.4 其他一些调度类的尝试 @@ -539,11 +543,11 @@ linux 调度器定义了多个调度类, 不同调度类的调度优先级不同 |:---:|:----:| | [同时多线程](https://zh.alegsaonline.com/art/90586) | 一句话介绍 交错式多线程 (IMT), 同步多线程 (SMT), 芯片级多处理 (CMP 或多核处理器) | | [超能课堂 (104)-- 超线程 / SMT 多线程技术有什么用?](https://www.expreview.com/56674.html) | 简单介绍了 SMT 的工作原理 | -| [说一说超线程 / 同步多线程(HT/SMT)技术那些事儿](https://zhuanlan.zhihu.com/p/352676442) | SMT 一些疑惑解答 | +| [说一说超线程 / 同步多线程(HT/SMT)技术那些事儿](https://zhuanlan.zhihu.com/p/352676442) | SMT 一些疑惑解答 | | [被误解的 CPU 利用率、超线程、动态调频 —— CPU 性能之迷 Part 1](https://zhuanlan.zhihu.com/p/534119705) | 介绍了 ITMT 3.0 以及 SMT 技术 | | [曲速未来 揭露:新的 PortSmash 超线程 CPU Vuln 可以窃取解密密钥](https://zhuanlan.zhihu.com/p/48625343) | PortSmash 漏洞 (CVE-2018-5407), 该漏洞使用定时攻击来窃取来自同一 CPU 核心中运行 SMT / 超线程的其他进程的信息 | | [超线程技术究竟好不好?](https://www.zhihu.com/question/290385913) | NA | -| [超威半导体(AMD)的超线程技术和英特尔(Intel)的超线程技术有差别吗?](https://www.zhihu.com/question/350083255) | NA | +| [超威半导体(AMD)的超线程技术和英特尔(Intel)的超线程技术有差别吗?](https://www.zhihu.com/question/350083255) | NA | | [CPU 的超线程技术提升 IPC 吗?](https://www.zhihu.com/question/404826890), [关于 SMT 的性能收益](https://zhuanlan.zhihu.com/p/164603076) | NA | | [超线程的两个线程资源是动态分配的还是固定一半一半的?](https://www.zhihu.com/question/59721493) | NA | | [英特尔超线程技术](https://baike.baidu.com/item / 英特尔超线程技术 / 10233952) | NA | @@ -4003,8 +4007,7 @@ y = (1 - \frac{pct^{2}}{10000^{2}} \times x^{2}) \times llc\_weight | 2021/12/03 | Tim Chen | [Make Cluster Scheduling Configurable](https://lkml.org/lkml/2021/12/3/891) | Cluster Scheduling 并不适用于所有场景, 因此这组补丁支持了在运行时和引导时可以动态配置 Cluster Scheduling. 可以通过启动参数 `sched_cluster={1|0}` 来在启动时开启和关闭, 也可以通过 `/proc/sys/kernel/sched_cluster` 接口在运行时动态开启和关闭.
当系统负载适中时, 值得做额外的负载平衡来平衡 cluster 之间的负载, 以减少 cluster 内资源的争用. 但是如果系统负载较大, 各个资源已经得到充分利用, cluster 之间的负载平衡不太可能有助于减少 cluster 的资源争用, 因为 cluster 内已经完全繁忙.
同时由于不感知性能异构的 CPU 类型, 造成了 Intel Alder Lake CPU 上性能退化, 参见 [Linux 5.16's New Cluster Scheduling Is Causing Regression, Further Hurting Alder Lake](https://www.phoronix.com/scan.php?page=article&item=linux-516-regress&num=3). 因此在 x86 hybrid 类型的 CPU 上禁用 Cluster Scheduling.
在一个有 24 个 Atom 内核的 Jacobsville 系统上 (每个 cluster 有 4 个 Atom CPU 核共享一个 L2), 在 24 个 CPU 的系统上运行 mcf 基准测试, 从非常低的负载 1 个基准测试副本到 24 个基准测试副本. 我们看到, 在中等负载时吞吐量得到了提高, 但当系统满负载时, Cluster Scheduling 几乎没有什么提升.
不过 Peter 最终直接选择在 x86 hybrid CPUs 上禁用 cluster. 参见 commit [cabdc3a8475b ("sched,x86: Don't use cluster topology for x86 hybrid CPUs")](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=cabdc3a8475b918e55744f43719b26a82dc8fa6b). | v1 ☐ | [LORE 0/5](https://lkml.kernel.org/lkml/cover.1638563225.git.tim.c.chen@linux.intel.com), [Peter Zijlstra COMMIT](https://lore.kernel.org/all/163899885798.11128.4032422680527135079.tip-bot2@tip-bot2) | | 2022/01/26 | Yicong Yang | [sched/fair: Scan cluster before scanning LLC in wake-up path](https://lore.kernel.org/all/20220822073610.27205-1-yangyicong@huawei.com) | v5 之前叫 [sched/fair: Wake task within the cluster when possible](https://lore.kernel.org/all/20220126080947.4529-1-yangyicong@hisilicon.com). 这个补丁集负责唤醒路径的 cluster 感知, 在扫描整个 LLC 之前, 先在同一集群中其他的 CPU 尝试一下, 以使这些任务能够相互通信.
1. 引入 SD_CLUSTER 标记 cluster 域, 使用 per_cpu(sd_cluster, cpu) 和 per_cpu(sd_share_id, cpu) 标记 CPU 所属的 cluster 及其 ID
2. 接着 select_idle_cpu() 试图在扫描整个 LLC 之前先通过 scan_cluster() 找到目标 CPU cluster 域 per_cpu(sd_cluster, target) 内空闲的 CPU, 以获得更低的延迟. | v2 ☐☑✓ | [LORE 0/2](https://lore.kernel.org/lkml/20211215041149.73171-1-yangyicong@hisilicon.com)
*-*-*-*-*-*-*-*
[LORE v2,0/2](https://lore.kernel.org/all/20220126080947.4529-1-yangyicong@hisilicon.com)
*-*-*-*-*-*-*-*
[LORE v3,0/2](https://lore.kernel.org/lkml/20220608095758.60504-1-yangyicong@hisilicon.com)
*-*-*-*-*-*-*-*
[LORE v4,0/2](https://lore.kernel.org/lkml/20220609120622.47724-1-yangyicong@hisilicon.com)
*-*-*-*-*-*-*-*
[LORE v5,0/2](https://lore.kernel.org/lkml/20220720081150.22167-1-yangyicong@hisilicon.com)
*-*-*-*-*-*-*-*
[LORE v6,0/2](https://lore.kernel.org/lkml/20220726074758.46686-1-yangyicong@huawei.com)
*-*-*-*-*-*-*-*
[LORE v7,0/2](https://lore.kernel.org/all/20220822073610.27205-1-yangyicong@huawei.com) | | 2023/04/10 | K Prateek Nayak | [arch/x86: Set L2 Cache ID on AMD processors](https://lore.kernel.org/all/20230410163527.1626-1-kprateek.nayak@amd.com) | 将 Cluster Scheduler 扩展到 AMD 处理器上. 将 "l2c_id" 与拓扑扩展 "TOPOEXT" 特性连接起来, 用于在 AMD 处理器上设置, 以便共享相同 L2 缓存的线程集可以正确地映射到相同的集群 ID. 参见 phoronix 报道 [Linux Cluster-Aware Scheduling Being Extended To AMD Processors](https://www.phoronix.com/news/AMD-Linux-L2-Cluster-Scheduler) | v1 ☐☑✓ | [LORE v1,0/2](https://lore.kernel.org/all/20230410163527.1626-1-kprateek.nayak@amd.com) | -| 2023/05/04 | Tim Chen | [Enable Cluster Scheduling for x86 Hybrid CPUs](https://lore.kernel.org/all/cover.1683156492.git.tim.c.chen@linux.intel.com) | 当集群调度首次引入 x86 时, 人们注意到, 在混合 CPU 上进行集群调度时, 单线程任务通常会在 Atom 核 (或 E 核) 上完成, 而不是在空闲的 Big 核 (或 P 核) 上, 从而导致性能降低. 因此, x86 混合 CPU 上的集群调度被禁用. 参见: [Linux 5.16's New Cluster Scheduling Is Causing Regression, Further Hurting Alder Lake](https://www.phoronix.com/review/linux-516-regress). Ricardo 最近推出了 [sched: Avoid unnecessary migrations within SMT domains](https://lore.kernel.org/lkml/20230406203148.19182-1-ricardo.neri-calderon@linux.intel.com) 系列, 极大地改进了 x86 混合 CPU 上 P 核和 E 核之间的负载平衡逻辑. 然而, 该补丁系列不足以允许在混合 x86 CPU 上启用集群调度. 此补丁系列提供了一些额外的修复程序, 用于在由 Big Core 的 SMT CPU 组成的集群调度组和由 Atom CPU 组成的群集调度组之间进行负载平衡. 在 Ricardo 的补丁系列之上继续 APPLY 当前补丁, 可以在 P 核和 E 核集群之间适当平衡负载. 空闲 CPU 按正确顺序使用: 1). 空闲 P 核上的 SMT CPU, 2). 空闲 E 核, 3). 未使用的 SMT CPU 和繁忙的同级.
在 x86 上, Cluster 中的 CPU 共享 L2. 现在, 在启用 Cluster Scheduling 的情况下, Cluster 之间的负载得到了平衡, 从而可能减少 L2 争用. 参见 [Intel Posts New Linux Patches For Cluster Scheduling With Hybrid CPUs](https://www.phoronix.com/news/Intel-Hybrid-CPU-Cluster-Sched) | v1 ☐☑✓ | [LORE v1,0/4](https://lore.kernel.org/lkml/20220825225529.26465-1-ricardo.neri-calderon@linux.intel.com)
*-*-*-*-*-*-*-*
[LORE v2,0/7](https://lore.kernel.org/lkml/20221122203532.15013-1-ricardo.neri-calderon@linux.intel.com)
*-*-*-*-*-*-*-*
[LORE v3,0/10](https://lore.kernel.org/lkml/20230207045838.11243-1-ricardo.neri-calderon@linux.intel.com)
*-*-*-*-*-*-*-*
[LORE v4,00/12](https://lore.kernel.org/lkml/20230406203148.19182-1-ricardo.neri-calderon@linux.intel.com) | - +| 2023/05/04 | Tim Chen | [Enable Cluster Scheduling for x86 Hybrid CPUs](https://lore.kernel.org/all/cover.1683156492.git.tim.c.chen@linux.intel.com) | 当集群调度首次引入 x86 时, 人们注意到, 在混合 CPU 上进行集群调度时, 单线程任务通常会在 Atom 核 (或 E 核) 上完成, 而不是在空闲的 Big 核 (或 P 核) 上, 从而导致性能降低. 因此, x86 混合 CPU 上的集群调度被禁用. 参见: [Linux 5.16's New Cluster Scheduling Is Causing Regression, Further Hurting Alder Lake](https://www.phoronix.com/review/linux-516-regress) 和 [Intel Updates Cluster Scheduling Linux Patches For Hybrid CPUs](https://www.phoronix.com/news/Intel-Cluster-Sched-Hybrid-V2). Ricardo 最近推出了 [sched: Avoid unnecessary migrations within SMT domains](https://lore.kernel.org/lkml/20230406203148.19182-1-ricardo.neri-calderon@linux.intel.com) 系列, 极大地改进了 x86 混合 CPU 上 P 核和 E 核之间的负载平衡逻辑. 然而, 该补丁系列不足以允许在混合 x86 CPU 上启用集群调度. 此补丁系列提供了一些额外的修复程序, 用于在由 Big Core 的 SMT CPU 组成的集群调度组和由 Atom CPU 组成的群集调度组之间进行负载平衡. 在 Ricardo 的补丁系列之上继续 APPLY 当前补丁, 可以在 P 核和 E 核集群之间适当平衡负载. 空闲 CPU 按正确顺序使用: 1). 空闲 P 核上的 SMT CPU, 2). 空闲 E 核, 3). 未使用的 SMT CPU 和繁忙的同级.
在 x86 上, Cluster 中的 CPU 共享 L2. 现在, 在启用 Cluster Scheduling 的情况下, Cluster 之间的负载得到了平衡, 从而可能减少 L2 争用. 参见 [Intel Posts New Linux Patches For Cluster Scheduling With Hybrid CPUs](https://www.phoronix.com/news/Intel-Hybrid-CPU-Cluster-Sched) | v1 ☐☑✓ | [LORE v1,0/4](https://lore.kernel.org/lkml/20220825225529.26465-1-ricardo.neri-calderon@linux.intel.com)
*-*-*-*-*-*-*-*
[LORE v2,0/7](https://lore.kernel.org/lkml/20221122203532.15013-1-ricardo.neri-calderon@linux.intel.com)
*-*-*-*-*-*-*-*
[LORE v3,0/10](https://lore.kernel.org/lkml/20230207045838.11243-1-ricardo.neri-calderon@linux.intel.com)
*-*-*-*-*-*-*-*
[LORE v4,00/12](https://lore.kernel.org/lkml/20230406203148.19182-1-ricardo.neri-calderon@linux.intel.com)
*-*-*-*-*-*-*-*
[LORE v2,0/6](https://lore.kernel.org/all/cover.1683156492.git.tim.c.chen@linux.intel.com) | ### 5.5.2 Multiple LLCs ------- @@ -5836,7 +5839,7 @@ $$$ 使用 `avg_vruntime(struct cfs_rq *cfs_rq)` 可以获取实际的归一后的平均 vruntime 值. -cfs_rq->avg_vruntime 和上缓存了 cfs_rq 上所有任务 (调度实体) 的带 load.weight 加权的 vruntime 累积偏差, cfs_rq->avg_load 则缓存了 cfs_rq 上所有任务 (调度实体) 的累积 load.weight. 两者比值就近似为: cfs_rq 上上所有任务 (调度实体) 的 vruntime (相距离 cfs_rq->min_vruntime) 的带权平均偏差. 再加上 cfs_rq->min_vruntime 就是 cfs_rq 当前的带权归一化的平均 vruntime. 这个值的显示理论含义可以近似为: 就绪队列上所有任务平均获取的(虚拟)运行时间. +cfs_rq->avg_vruntime 和上缓存了 cfs_rq 上所有任务 (调度实体) 的带 load.weight 加权的 vruntime 累积偏差, cfs_rq->avg_load 则缓存了 cfs_rq 上所有任务 (调度实体) 的累积 load.weight. 两者比值就近似为: cfs_rq 上上所有任务 (调度实体) 的 vruntime (相距离 cfs_rq->min_vruntime) 的带权平均偏差. 再加上 cfs_rq->min_vruntime 就是 cfs_rq 当前的带权归一化的平均 vruntime. 这个值的显示理论含义可以近似为: 就绪队列上所有任务平均获取的 (虚拟) 运行时间. $$avg = frac{avg\_vruntime_{cfs\_rq}}{avg\_load_{cfs\_rq}} = \frac{\sum_{i=0}^{N} (vruntime_{se} - min\_vruntime_{cfs\_rq}) \times load\_weight}{\sum_{i=0}^{N} load\_weight}$$ $$avg\_vruntime = min\_vruntime_{cfs\_rq} + avg = min\_vruntime_{cfs\_rq} + frac{avg\_vruntime_{cfs\_rq}}{avg\_load_{cfs\_rq}} = min\_vruntime_{cfs\_rq} + \frac{\sum_{i=0}^{N} (vruntime_{se} - min\_vruntime_{cfs\_rq}) \times load\_weight}{\sum_{i=0}^{N} load\_weight}$$ @@ -5844,11 +5847,9 @@ $$avg\_vruntime = min\_vruntime_{cfs\_rq} + avg = min\_vruntime_{cfs\_rq} + frac > 此外还有一个细节, 由于 CFS 进程, current(cfs_rq->curr) 每次被 PICK 之后, 会从红黑树出队, 因此 avg_vruntime() 和 entity_eligible() 计算时需要把 cfs_rq->curr 也统计进来. -* entity_eligible() +* entity_eligible()> EEVDF 会对每个进程计算出该进程应该得到的时间和它实际得到的时间之间的差异. 这个差异被称为 "lag". lag 值为正的进程就没有得到公平的份额, 应该比 lag 值为负的过程要更早调度. -> EEVDF 会对每个进程计算出该进程应该得到的时间和它实际得到的时间之间的差异. 这个差异被称为 "lag". lag 值为正的进程就没有得到公平的份额, 应该比 lag 值为负的过程要更早调度. - -有了 cfs_rq 的平均 vruntime, 即就绪队列上所有任务的平均虚拟运行时间, 那么进程实际获得的虚拟运行时间 se->vruntime 相距平均虚拟运行时间 vruntime 的距离, 就是进程(调度实体)的 vlag 值. EEVDF 认为 vlag >= 0 的任务是 eligible, vlag < 0 的任务是 !eligible 的. +有了 cfs_rq 的平均 vruntime, 即就绪队列上所有任务的平均虚拟运行时间, 那么进程实际获得的虚拟运行时间 se->vruntime 相距平均虚拟运行时间 vruntime 的距离, 就是进程 (调度实体) 的 vlag 值. EEVDF 认为 vlag >= 0 的任务是 eligible, vlag < 0 的任务是 !eligible 的. $$lag = avg\_vruntime_{cfs_rq} - vruntime_{se}$$