mirror of
https://github.com/gatieme/LDD-LinuxDeviceDrivers.git
synced 2026-11-09 08:38:04 +08:00
description: update_blocked_averages
This commit is contained in:
1 parent
c54775efc8
commit
4e1ccd7609
2 files changed
+61
-22
No files matched your search
@@ -254,6 +254,9 @@ SCHED_IDLE 跟 SCHED_BATCH 一样, 是 CFS 中的一个策略, SCHED\_IDLE 的
|
||||
|
||||
因此 Linux 社区里面并没有多少人会使用 SCHED_IDLE 调度策略, 因此自从Linux 2.6.23 引入之后, 就没人对它进行改进.
|
||||
|
||||
#### 1.1.5.1 引入 SCHED_IDLE
|
||||
-------
|
||||
|
||||
| 时间 | 作者 | 特性 | 描述 | 是否合入主线 | 链接 |
|
||||
|:----:|:----:|:---:|:----:|:---------:|:----:|
|
||||
| 2007/07/09 | Ingo Molnar <mingo@elte.hu> | [0e6aca43e08a sched: add SCHED_IDLE policy](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=0e6aca43e08a) | NA | v1 ☑ 2.6.23-rc1 | [PATCH HISTORY](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=0e6aca43e08a) |
|
||||
@@ -261,6 +264,9 @@ SCHED_IDLE 跟 SCHED_BATCH 一样, 是 CFS 中的一个策略, SCHED\_IDLE 的
|
||||
| 2009/01/15 | Peter Zijlstra <a.p.zijlstra@chello.nl> | [cce7ade80369 sched: SCHED_IDLE weight change](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=cce7ade80369) | 将 SCHED\_IDLE 权重从 2 增加到 3, 这将提供更稳定的 vruntime. | v1 ☑ 2.6.23-rc1 | [PATCH HISTORY](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=cce7ade80369) |
|
||||
|
||||
|
||||
#### 1.1.5.2 Fallback to sched-idle CPU
|
||||
-------
|
||||
|
||||
注意, 在 select_task_rq() 调用中并没有针对 SCHED\_IDLE 调度策略的相应处理, 因此我们并没能做到尽量把新唤醒的 SCHED_NORMAL task 放到当前正在运行 SCHED_IDLE task 的 CPU 上去. 之前的 select_task_rq_fair() 中更倾向于寻找一个 IDLE 的 CPU.
|
||||
|
||||
那么这就有一个矛盾的地方了, 那就是在选核的时候, 如果当前 CPU 上正运行 SCHED_IDLE 的进程. 那么选择这样的 CPU 更合适, 还是继续往下寻找 idle 的 CPU 更合适?
|
||||
@@ -274,14 +280,27 @@ SCHED_IDLE 跟 SCHED_BATCH 一样, 是 CFS 中的一个策略, SCHED\_IDLE 的
|
||||
后续对此补丁还有一些细微的优化,比如 [sched/fair: Make sched-idle cpu selection consistent throughout 1143783 diffmboxseries](https://lore.kernel.org/patchwork/patch/1143783), 优化了选核的逻辑, 之前的逻辑中认为, 如果 find_idlest_group_cpu/sched_idle_core 中如果查找不到 avaliable_idle_cpu(处于 IDLE 状态的 CPU), 才寻找 sched_idle_cpu(运行 SCHED_IDLE 的 CPU), 即优先 IDLE, 其次 SCHED_IDLE. 而 select_idle_sibling 中则认为 avaliable_idle_cpu 和 sched_idle_cpu 都是可以接受的, 找到了任何一个满足要求的则返回. 可以看到不同的选核流程下, 对 avaliable_idle_cpu 和 sched_idle_cpu 的接受程度不同. 但是这其实本身就是一个没有对错的问题, 其实我们选核的时候, 不一定 IDLE 一定是最优的, 如果直接选一个 sched_idle_cpu 的 CPU 有时候是优于 avaliable_idle_cpu 的, 因为这些核是不需要(发 IPI)唤醒的. 因此这个补丁就将选核流程上做了归一, 所有的选核流程都将 avaliable_idle_cpu 和 sched_idle_cpu 同等对待, 只要找到了一个 avaliable_idle_cpu 或者 sched_idle_cpu 都是可以接受的, 没必要在 avaliable_idle_cpu 找不到的时候才去选则 sched_idle_cpu
|
||||
|
||||
| 时间 | 作者 | 特性 | 描述 | 是否合入主线 | 链接 |
|
||||
|:----:|:----:|:----:|:---:|:------:|:---:|
|
||||
|:----:|:----:|:---:|:---:|:-----------:|:---:|
|
||||
| 2019/6/26 | Viresh Kumar <viresh.kumar@linaro.org> | [sched/fair: Fallback to sched-idle CPU in absence of idle CPUs](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/log/?id=3c29e651e16dd3b3179cfb2d055ee9538e37515c) | CFS SCHED_NORMAL 进程在选核的时候, 之前优先选择 IDLE 的 CPU, 现在在没有 IDLE 的 CPU 可选的时候, 也倾向于选择只有 SCHED_IDLE 的进程在运行的 CPU | v3 ☑ [5.4-rc1](https://kernelnewbies.org/Linux_5.4#Core_.28various.29) | [LWN](https://lwn.net/Articles/805317), [PatchWork](https://lore.kernel.org/patchwork/cover/1094197), [lkml](https://lkml.org/lkml/2019/6/26/16)<br>*-*-*-*-*-*-*-* <br>[LORE v3,0/2](https://lore.kernel.org/all/cover.1561523542.git.viresh.kumar@linaro.org) |
|
||||
| 2019/10/24 | NA | [sched/fair: Make sched-idle cpu selection consistent throughout 1143783 diffmboxseries](https://lore.kernel.org/patchwork/patch/1143783) | 重构了 SCHED_IDLE 时的选核逻辑, 所有的选核流程都将 avaliable_idle_cpu 和 sched_idle_cpu 同等对待 | v1 ☑ 5.4-rc1 | [PatchWork](https://lore.kernel.org/patchwork/patch/1143783) |
|
||||
| 2020/12/23 | NA | [sched/fair: Load balance aggressively for SCHED_IDLE CPUs](https://lkml.org/lkml/2020/1/8/112) | LOAD_BALANCE 感知 SCHED_IDLE 优化, SCHED_IDLE 的 CPU 虽然运行着进程但是在调度器看来其实也是空闲的, 应该积极地进行负载均衡 | v1 ☑ 5.6-rc1 | [LKML](https://lkml.org/lkml/2020/1/8/112) |
|
||||
| 2019/10/24 | NA | [sched/fair: Make sched-idle cpu selection consistent throughout](https://lore.kernel.org/patchwork/patch/1143783) | 重构了 SCHED_IDLE 时的选核逻辑, 所有的选核流程都将 avaliable_idle_cpu 和 sched_idle_cpu 同等对待 | v1 ☑ 5.4-rc1 | [PatchWork](https://lore.kernel.org/patchwork/patch/1143783) |
|
||||
|
||||
#### 1.1.5.3 sched-idle Load Balancing
|
||||
-------
|
||||
|
||||
| 时间 | 作者 | 特性 | 描述 | 是否合入主线 | 链接 |
|
||||
|:----:|:----:|:---:|:---:|:-----------:|:---:|
|
||||
| 2019/12/24 | Viresh Kumar <viresh.kumar@linaro.org> | [sched/fair: Load balance aggressively for SCHED_IDLE CPUs](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/log/?id=323af6deaf70f204880caf94678350802682e0dc) | LOAD_BALANCE 感知 SCHED_IDLE 优化, SCHED_IDLE 的 CPU 虽然运行着进程但是在调度器看来其实也是空闲的, 应该积极地进行负载均衡 | v1 ☑✓ 5.6-rc1 | [LORE](https://lore.kernel.org/all/885b1be9af68d124f44a863f54e337f8eb6c4917.1577090998.git.viresh.kumar@linaro.org)<br>*-*-*-*-*-*-*-* <br>[LKML](https://lkml.org/lkml/2020/1/8/112) |
|
||||
| 2021/02/22 | NA | [sched: pull tasks when CPU is about to run SCHED_IDLE tasks](https://lore.kernel.org/patchwork/patch/1382990) | 在 CPU 从 SCHED_NORMAL 进程切换到 SCHED_IDLE 任务之前, 尝试通过 load_balance 从其他核上 PULL SCHED_NORMAL 进程过来执行. | v2 | [2020/12/27 v1](https://lore.kernel.org/patchwork/patch/1356241), [2021/02/22 v2](https://lore.kernel.org/patchwork/patch/1143783) |
|
||||
| 2022/02/17 | Abel Wu <wuyun.abel@bytedance.com> | [introduce sched-idle balancing](https://lore.kernel.org/all/20220217154403.6497-1-wuyun.abel@bytedance.com) | 当前负载平衡主要基于 cpu capacity 和 task util, 这在整体吞吐量的 POV 中是有意义的. 虽然如果存在 sched 闲置或闲置 RQ, 则可以通过减少过载 CFS RQ 的数量来完成一些改进. 当 CFS RQ 上有多个可伸缩的非闲置任务时(因为 schedidle CPU 被视为闲置 CPU), CFS RQ 被认为是过载的. 空闲任务计入 rq->cfs.idle_h_nr_running.<br>过载的 CFS RQ 可能会导致两种任务类型的性能问题:<br>1. 对于诸如 SCHED_NORMAL 之类的延迟关键任务, RQ 中的等待时间将增加并导致更高的 PCT99 延迟, 并且如果存在 SCHED_DILE, 批处理任务 SCHED_BATCH 可能无法充分利用 CPU 容量, 因此吞吐量较差.<br>所以简而言之, sched-idle balancing 的目标是让非闲置任务充分利用 CPU 资源.<br>为此, 我们主要做两件事:<br>1. 为 sched-idle 的 CPU 拉取 non-idle 的任务来运行, 或者将 overload CPU 上的任务拉取到 idle 的 CPU 上.<br>2. 防止在 RQ 中 PULL 出最后一个非闲置任务. 此外 overloaded CPUs 的掩码会周期性更新, 空闲路径在 LLC 域上. 这个 cpumask 还将在 SIS 中用作过滤器, 改善空闲的 CPU 搜索. | v1 ☐☑✓ | [LORE v1,0/5](https://lore.kernel.org/all/20220217154403.6497-1-wuyun.abel@bytedance.com)<br>*-*-*-*-*-*-*-* <br>[LORE v2,0/2](https://lore.kernel.org/lkml/20220409135104.3733193-1-wuyun.abel@bytedance.com) |
|
||||
|
||||
|
||||
#### 1.1.5.4 cgroup SCHED_IDLE support
|
||||
-------
|
||||
|
||||
| 时间 | 作者 | 特性 | 描述 | 是否合入主线 | 链接 |
|
||||
|:----:|:----:|:---:|:---:|:-----------:|:---:|
|
||||
| 2021/08/20 | Josh Don <joshdon@google.com> |[cgroup SCHED_IDLE support/SCHED_IDLE extensions](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/log/?id=304000390f88d049c85e9a0958ac5567f38816ee) | 1. cgroup [组支持 SCHED_IDLE](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=304000390f88)<br>2. RQ 上维护了 [idle_nr_running](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=a480addecc0d) 的跟踪.<br>3. 引入 [`sysctl_sched_idle_min_granularity`](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=51ce83ed523b), 当 SCHED_IDLE 任务与正常任务竞争时适用, 表示 SCHED_IDLE 任务的最小抢占粒度. 这样在与普通实体竞争时, 通过对 SCHED_IDLE 的调度实体使用较小的、无伸缩性的最小抢占粒度(由 sched_slice 计算). 可以减少普通调度实体切回来的延迟, 但代价是增加了SCHED_IDLE实体的上下文切换频率. 有效地减少了普通调度实体在与 SCHED_IDLE 调度实体竞争时的轮询延迟.<br>4. 在 place_entity() 中对于 `SCHED_IDLE` 实体唤醒时得到的补偿减少到 `sysctl_sched_min_granularity`. 因此, 唤醒的 SCHED_IDLE 实体将花费更长的时间来抢占正常实体. 此更改的好处是, 降低了新唤醒的 `SCHED_IDLE` 实体在阻塞之前抢占短期运行的普通调度实体的可能性. | v3 ☑ [5.15-rc1](https://kernelnewbies.org/LinuxChanges#Linux_5.15.cgroup_support_for_SCHED_IDLE) | [2021/06/08 v1](https://lore.kernel.org/lkml/20210608231132.32012-1-joshdon@google.com)<br>*-*-*-*-*-*-*-* <br>[2021/7/29 LKML v2 0/2](https://lkml.org/lkml/2021/7/29/1201)<br>*-*-*-*-*-*-*-* <br>[2021/08/20 LORE v3,0/4](https://lore.kernel.org/all/20210820010403.946838-1-joshdon@google.com)<br>*-*-*-*-*-*-*-* <br>[关键 commit](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=304000390f88d049c85e9a0958ac5567f38816ee) |
|
||||
| 2022/02/17 | Abel Wu <wuyun.abel@bytedance.com> | [introduce sched-idle balancing](https://lore.kernel.org/all/20220217154403.6497-1-wuyun.abel@bytedance.com) | 当前负载平衡主要基于 cpu capacity 和 task util, 这在整体吞吐量的 POV 中是有意义的. 虽然如果存在 sched 闲置或闲置 RQ, 则可以通过减少过载 CFS RQ 的数量来完成一些改进. 当 CFS RQ 上有多个可伸缩的非闲置任务时(因为 schedidle CPU 被视为闲置 CPU), CFS RQ 被认为是过载的. 空闲任务计入 rq->cfs.idle_h_nr_running.<br>过载的 CFS RQ 可能会导致两种任务类型的性能问题:<br>1. 对于诸如 SCHED_NORMAL 之类的延迟关键任务, RQ 中的等待时间将增加并导致更高的 PCT99 延迟, 并且如果存在 SCHED_DILE, 批处理任务 SCHED_BATCH 可能无法充分利用 CPU 容量, 因此吞吐量较差.<br>所以简而言之, sched-idle balancing 的目标是让非闲置任务充分利用 CPU 资源.<br>为此, 我们主要做两件事:<br>1. 为 sched-idle 的 CPU 拉取 non-idle 的任务来运行, 或者将 overload CPU 上的任务拉取到 idle 的 CPU 上.<br>2. 防止在 RQ 中 PULL 出最后一个非闲置任务. 此外 overloaded CPUs 的掩码会周期性更新, 空闲路径在 LLC 域上. 这个 cpumask 还将在 SIS 中用作过滤器, 改善空闲的 CPU 搜索. | v1 ☐☑✓ | [LORE v1,0/5](https://lore.kernel.org/all/20220217154403.6497-1-wuyun.abel@bytedance.com) |
|
||||
| 2019/12/24 | Viresh Kumar <viresh.kumar@linaro.org> | [sched/fair: Load balance aggressively for SCHED_IDLE CPUs](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/log/?id=323af6deaf70f204880caf94678350802682e0dc) | NA | v1 ☑✓ 5.6-rc1 | [LORE](https://lore.kernel.org/all/885b1be9af68d124f44a863f54e337f8eb6c4917.1577090998.git.viresh.kumar@linaro.org) |
|
||||
|
||||
|
||||
|
||||
### 1.1.6 吭哧吭哧跑计算 SCHED\_BATCH
|
||||
@@ -677,7 +696,7 @@ https://lore.kernel.org/lkml/157476581065.5793.4518979877345136813.stgit@buzz/
|
||||
| 时间 | 作者 | 特性 | 描述 | 是否合入主线 | 链接 |
|
||||
|:----:|:----:|:---:|:----:|:---------:|:----:|
|
||||
| 2007/08/09 | Ingo Molnar <mingo@elte.hu> | [sched: make the multiplication table more accurate](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=254753dc321ea2b753ca9bc58ac329557a20efac) | 对 prio_to_weight 和 prio_to_wmult 做一定的调整. | v1 ☐ | [ 2020/12/17 v1](https://lore.kernel.org/patchwork/cover/1396878) |
|
||||
| 2012/08/23 | pjt@google.com <pjt@google.com> | [sched: per-entity load-tracking](https://lore.kernel.org/all/20120823141422.444396696@google.com) | 20120823141422.444396696@google.com | v1 ☐☑✓ | [LORE v1,0/16](https://lore.kernel.org/all/20120823141422.444396696@google.com) |
|
||||
| 2012/08/23 | pjt@google.com <pjt@google.com> | [sched: per-entity load-tracking](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/log/?id=e9c84cb8d5f1b1ea6fcbe6190d51dc84b6975938) | PELT | v1 ☐☑✓ | [LORE v1,0/16](https://lore.kernel.org/all/20120823141422.444396696@google.com) |
|
||||
|
||||
|
||||
# 4 基于调度域的负载均衡
|
||||
@@ -883,7 +902,24 @@ Vincent Guittot 深耕与解决 load_balance 各种疑难杂症和不均衡状
|
||||
|
||||
|
||||
此外 update_blocked_averages 也是内核调度器一个非常耗时的操作.
|
||||
最早的时候, update_blocked_averages 是一个非常严重的性能瓶颈, [OOM and High CPU utilization in update_blocked_averages because of too many cfs_rqs in rq->leaf_cfs_rq_list](https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1747896). 原因在于 rq->leaf_cfs_rq_list 是当前 CPU 上所有处于活动状态的 cfs_rq 的有序队列, update_blocked_averages 大多数 cgroup 中启用 CPU 控制器的系统中的负载均衡路径中, CPU消耗较少, 调度延迟增加. 特别是在临时创建了多个 cgroup 分组(称为 cgroup 泄漏) 的特殊情况下, 这会导致内核在运行 update_blocked_average() 耗时过程, 每次运行都要花费数毫秒. perf top 查看, update_blocked_averages 函数的热点占比甚至达到 30% 左右.
|
||||
|
||||
#### 4.3.4.1 前世的 update_shares, 今生的 update_blocked_averages
|
||||
-------
|
||||
|
||||
| 时间 | 作者 | 特性 | 描述 | 是否合入主线 | 链接 |
|
||||
|:----:|:----:|:---:|:---:|:----------:|:----:|
|
||||
| 2022/05/05 | Peter Zijlstra <a.p.zijlstra@chello.nl> | [sched: simplify the group load balancer](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/log/?id=55e12e5e7b1d7e7c05a4be10cb5fd092c039aa78) | 引入 update_shares() 更新 sched_domain 下所有 task_group 之间的相对负载. 这是一项非常耗时的操作, 通过 walk_tg_tree() 遍历所有的 task_group, 然后[使用 `tg_shares_up() -=> __update_group_shares_cpu()`](https://elixir.bootlin.com/linux/v2.6.27/source/kernel/sched.c#L1490) 更新其[各个 sched_domain 层级之间](https://elixir.bootlin.com/linux/v2.6.27/source/kernel/sched.c#L1510)的相对负载. 这需要以自下而上的方式进行, 因为父 task_group 的 rq 权重 rq_weight 取决于其子组的份额 tg->shares. | v1 ☑✓ 2.6.27-rc1 | [LORE](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=55e12e5e7b1d7e7c05a4be10cb5fd092c039aa78) |
|
||||
| 2010/11/15 | Paul Turner <pjt@google.com> | [reduce overhead for tg->shares distribution](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/log/?id=9437178f623a19af5951808d880a8599f66ac150) | 重构了整个 update_shares() -=> update_shares_cpu() 的逻辑, 优化了其整体开销. update_shares_cpu() 的工作被拆分成了两个主要流程, 各层级 task_group [相对权重的更新](https://elixir.bootlin.com/linux/v2.6.38/source/kernel/sched_fair.c#L2126)被 update_cfs_shares() 接管, 而 update_cfs_load() 则完成了[相对负载的更新](https://elixir.bootlin.com/linux/v2.6.38/source/kernel/sched_fair.c#L2120). | v4 ☑✓ 2.6.38-rc1 | [LORE v4,0/11](https://lore.kernel.org/all/20101115234659.610333554@google.com) |
|
||||
| 2012/8/23 | Paul Turner <pjt@google.com> | [sched: Refactor update_shares_cpu() -> update_blocked_averages()](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=48a1675323fa1b7844e479ad2a4469f4558c0f79) | [per-entity load-tracking](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/log/?id=e9c84cb8d5f1b1ea6fcbe6190d51dc84b6975938) 的其中 2 个补丁. [COMMIT1](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=82958366cfea1a50e7e90907b2d55ae29ed69974) 将 update_cfs_shares() 从 update_shares_cpu() 中移除, 自此 update_shares() -=> update_shares_cpu() 中要完成的工作已经脱离了之前的语义, 其最主要的工作已经被局限于被阻塞调度实体负载的周期性衰减, 即 Blocked Load 的更新. 因此 [COMMIT2](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=48a1675323fa1b7844e479ad2a4469f4558c0f79) 将函数重命名为 `update_blocked_averages() -=> __update_blocked_averages_cpu()`, 并放大了 rq-lock 的持有范围. | v1 ☑✓ 3.8 | [LWN](https://lwn.net/Articles/531853), [LORE v1,00/16](https://lore.kernel.org/lkml/20120823141422.444396696@google.com) |
|
||||
| 2012/8/23 | Yuyang Du <yuyang.du@intel.com> | [Rewrite runnable load and utilization average tracking](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/log/?id=7ea241afbf4924c58d41078599f7a32ba49fb985) | 重构组调度的 PELT 跟踪, 在每次更新平均负载的时候, 更新整个 CFS_RQ 的平均负载 | v10 ☑ 4.3-rc1 | [LWN](https://lwn.net/Articles/579066), [LORE v10,0/7](https://lore.kernel.org/all/1436918682-4971-1-git-send-email-yuyang.du@intel.com/), [lkml](https://lkml.org/lkml/2015/7/15/159) |
|
||||
|
||||
|
||||
|
||||
#### 4.3.4.2 optimize update_blocked_averages to O(nr_cgroups)
|
||||
-------
|
||||
|
||||
|
||||
update_blocked_averages() 在多个场景都被发现成为非常严重的性能瓶颈, [OOM and High CPU utilization in update_blocked_averages because of too many cfs_rqs in rq->leaf_cfs_rq_list](https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1747896). 原因在于 rq->leaf_cfs_rq_list 是当前 CPU 上所有处于活动状态的 cfs_rq 的有序队列, update_blocked_averages 大多数 cgroup 中启用 CPU 控制器的系统中的负载均衡路径中, CPU消耗较少, 调度延迟增加. 特别是在临时创建了多个 cgroup 分组(称为 cgroup 泄漏) 的特殊情况下, 这会导致内核在运行 update_blocked_average() 耗时过程, 每次运行都要花费数毫秒. perf top 查看, update_blocked_averages 函数的热点占比甚至达到 30% 左右.
|
||||
|
||||
为此主线体现了解决思路, 通过删除空的和完全衰减的 cfs_rq 来减低遍历的层次和开销.
|
||||
|
||||
@@ -898,9 +934,8 @@ Vincent Guittot 深耕与解决 load_balance 各种疑难杂症和不均衡状
|
||||
|
||||
| 时间 | 作者 | 特性 | 描述 | 是否合入主线 | 链接 |
|
||||
|:----:|:----:|:---:|:---:|:----------:|:----:|
|
||||
| 2015/07/15 | Vincent Guittot <vincent.guittot@linaro.org> | [sched/fair: Implement update_blocked_averages() for CONFIG_FAIR_GROUP_SCHED=n](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=6c1d47c0827304949e0eb9479f4d587f226fac8b) | 未开启 CFS 组调度时, 实现 update_blocked_averages. | v1 ☑ 4.3-rc1 | [commit](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=6c1d47c0827304949e0eb9479f4d587f226fac8b) |
|
||||
| 2017/04/24 | Tejun Heo | [sched/fair: Fix O(nr_cgroups) in load balance path](https://lore.kernel.org/patchwork/patch/783385) | 优化 update_blocked_averages 的负载 | v1 ☑ 4.13-rc1 | [PatchWork](https://lore.kernel.org/patchwork/patch/783385) |
|
||||
| 2019/02/06 | Vincent Guittot | [sched/fair: Fix O(nr_cgroups) in load balance path]()](https://lore.kernel.org/patchwork/cover/1039223) | 优化 update_blocked_averages 的负载 | v1 ☑ 5.1-rc1 | [PatchWork](https://lore.kernel.org/patchwork/patch/1039223) |
|
||||
| 2017/04/24 | Tejun Heo | [sched/fair: Fix O(nr_cgroups) in load balance path](https://lore.kernel.org/patchwork/patch/783385) | 优化 update_blocked_averages 的负载 | v1 ☑✓ 4.13-rc1 | [PatchWork](https://lore.kernel.org/patchwork/patch/783385) |
|
||||
| 2019/02/06 | Vincent Guittot | [sched/fair: Fix O(nr_cgroups) in load balance path]()](https://lore.kernel.org/patchwork/cover/1039223) | 优化 update_blocked_averages 的负载 | v1 ☑✓ 5.1-rc1 | [PatchWork](https://lore.kernel.org/patchwork/patch/1039223) |
|
||||
|
||||
|
||||
### 4.3.5 active load_balance
|
||||
@@ -1398,7 +1433,7 @@ void nohz_run_idle_balance(int cpu)
|
||||
|
||||
| 时间 | 作者 | 特性 | 描述 | 是否合入主线 | 链接 |
|
||||
|:----:|:----:|:---:|:---:|:----------:|:----:|
|
||||
| 2021/01/22 | Joel Fernandes (Google)" <joel@joelfernandes.org> | [sched/fair: Rate limit calls to update_blocked_averages() for NOHZ](https://lore.kernel.org/lkml/20210122154600.1722680-1-joel@joelfernandes.org) | 在运行ChromeOS Linux kernel v5.4 的 octacore ARM64 设备上, 发现有很多对 update_blocked_average() 的调用, 导致调度的开销增大, 造成 newilde_balance() 有时需要最多 500 微秒. 我在周期平衡器中也看到了这一点. 将 update_blocked_average() 调用速率限制为每秒 20 次 | v1 ☐ | [PatchWork](https://lore.kernel.org/lkml/20210122154600.1722680-1-joel@joelfernandes.org) |
|
||||
| 2021/01/22 | Joel Fernandes (Google)" <joel@joelfernandes.org> | [sched/fair: Rate limit calls to update_blocked_averages() for NOHZ](https://lore.kernel.org/lkml/20210122154600.1722680-1-joel@joelfernandes.org) | 在运行ChromeOS Linux kernel v5.4 的 octacore ARM64 设备上, 发现有很多对 update_blocked_averages() 的调用, 导致调度的开销增大, 造成 newilde_balance() 有时需要最多 500 微秒. 我在周期平衡器中也看到了这一点. 将 update_blocked_averages() 调用速率限制为每秒 20 次 | v1 ☐ | [PatchWork](https://lore.kernel.org/lkml/20210122154600.1722680-1-joel@joelfernandes.org) |
|
||||
| 2021/02/05 | Vincent Guittot <vincent.guittot@linaro.org> | [move update blocked load outside newidle_balance](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/log/?id=39b6a429c30482c349f1bb3746470fe473cbdb0f) | 优化 NEWLY_IDLE CPU 的 Blocked Load 更新. | v1 ☑✓ 5.13-rc1 | [LORE v1,0/6](https://lore.kernel.org/all/20210205114830.781-1-vincent.guittot@linaro.org)<br>*-*-*-*-*-*-*-* <br>[LORE v4,0/7](https://lore.kernel.org/all/20210224133007.28644-1-vincent.guittot@linaro.org) |
|
||||
| 2021/11/12 | Vincent Guittot <vincent.guittot@linaro.org> | [avoid spurious blocked load update](https://lore.kernel.org/all/20211112095857.7016-1-vincent.guittot@linaro.org) | 20211112095857.7016-1-vincent.guittot@linaro.org | v1 ☐☑✓ | [LORE v1,0/2](https://lore.kernel.org/all/20211112095857.7016-1-vincent.guittot@linaro.org) |
|
||||
|
||||
@@ -1896,6 +1931,8 @@ Oracle 数据库具有类似的虚拟化功能, 称为 Oracle Multitenant, 其
|
||||
| 2021/03/26 | Rik van Riel | [sched/fair: bring back select_idle_smt, but differently](https://lore.kernel.org/patchwork/patch/1402916) | Mel Gorman 上面的补丁在 9fe1f127b913("sched/fair: Merge select_idle_core/cpu()") 中做了一些出色的工作, 从而提高了内核查找空闲 CPU 的效率, 可以有效地降低任务等待运行的时间. 但是较多的均衡和迁移, 减少的局部性和相应的 L2 缓存丢失的增加会带来一些负面的效应. 这个补丁重新将 `select_idle_smt` 引入回来, 并做了优化, 修复了性能回归, 在搜索所有其他 CPU 之前, 检查 prev 的兄弟 CPU 是否空闲. | v2 ☑ v5.12-rc7 | [PatchWork](https://lore.kernel.org/patchwork/patch/1402916), [COMMIT](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=c722f35b513f807629603bbf24640b1a48be21b5) |
|
||||
| 2021/07/26 | Mel Gorman <mgorman@techsingularity.net> | [Modify and/or delete SIS_PROP](https://lore.kernel.org/patchwork/cover/1467090) | NA | RFC | [PatchWork RFC,0/9](https://lore.kernel.org/patchwork/cover/1467090) |
|
||||
| 2021/08/04 | Mel Gorman <mgorman@techsingularity.net> | [Reduce SIS scanning](https://lore.kernel.org/patchwork/cover/1472054) | 将 [Modify and/or delete SIS_PROP](https://lore.kernel.org/patchwork/cover/1467090) 拆开进行提交. | RFC ☐ | [PatchWork 0/2](https://lore.kernel.org/patchwork/cover/1472054) |
|
||||
| 2022/05/05 | Abel Wu <wuyun.abel@bytedance.com> | [sched/fair: filter out overloaded cpus in SIS](https://lore.kernel.org/all/20220505122331.42696-1-wuyun.abel@bytedance.com) | [introduce sched-idle balancing](https://lore.kernel.org/all/20220217154403.6497-1-wuyun.abel@bytedance.com) 的其中一个补丁, v3 之后单独发到社区. | v3 ☐☑✓ | [LORE](https://lore.kernel.org/all/20220505122331.42696-1-wuyun.abel@bytedance.com) |
|
||||
|
||||
|
||||
* SIS_PROP to search idle CPU based on sum of util_avg
|
||||
|
||||
@@ -2376,6 +2413,7 @@ CPUFreq 驱动是处理和平台相关的逻辑, Governor 中实现了具体的
|
||||
|:----:|:----:|:---:|:----------:|:---:|
|
||||
| 2016/02/23 | Steve Muckle 等 | [sched: scheduler-driven CPU frequency selection](https://lore.kernel.org/patchwork/cover/649930) | 调度器驱动的调频 cpufreq_sched | RFC v7 | [PatchWork](https://lore.kernel.org/patchwork/cover/649930), [lkml](https://lkml.org/lkml/2016/2/22/1037) |
|
||||
| 2016/03/22 | Rafael J. Wysocki | [cpufreq: schedutil governor](https://lore.kernel.org/patchwork/cover/660587) | 基于 utilization update callback callback 的 schedutil 的调频 governor | v6 ☑ 4.7-rc1 | [PatchWork](https://lore.kernel.org/patchwork/cover/660587), (https://lkml.org/lkml/2016/3/29/1041) |
|
||||
| 2016/03/13 | Michael Turquette <mturquette@baylibre.com> | [schedutil enhancements](https://lore.kernel.org/all/1457932932-28444-1-git-send-email-mturquette+renesas@baylibre.com) | 1457932932-28444-1-git-send-email-mturquette+renesas@baylibre.com | v1 ☐☑✓ | [LORE v1,0/8](https://lore.kernel.org/all/1457932932-28444-1-git-send-email-mturquette+renesas@baylibre.com) |
|
||||
|
||||
|
||||
3. schedutil 后续优化
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
| 时间 | 特性 | 描述 | 是否合入主线 | 链接 |
|
||||
|:----:|:----:|:---:|:------:|:---:|
|
||||
| 2012/8/23 | [per-entity load-tracking](https://lore.kernel.org/patchwork/cover/322242) | per-task 的负载跟踪首次引入内核 | V1 ☑3.8 | [LWN](https://lwn.net/Articles/531853), [PatchWork](https://lore.kernel.org/patchwork/cover/322242), [lkml](https://lkml.org/lkml/2012/8/23/267) |
|
||||
| 2012/8/23 | [per-entity load-tracking](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/log/?id=e9c84cb8d5f1b1ea6fcbe6190d51dc84b6975938) | per-task 的负载跟踪首次引入内核 | v1 ☑ 3.8 | [LWN](https://lwn.net/Articles/531853), [LORE 00/16](https://lore.kernel.org/lkml/20120823141422.444396696@google.com) |
|
||||
|
||||
第一个版本的 PELT 在 3.8 的时候合入主线.
|
||||
|
||||
@@ -28,6 +28,7 @@ aff3e4988444 sched: Account for blocked load waking back up
|
||||
18bf2805d9b3 sched: Maintain per-rq runnable averages
|
||||
9d85f21c94f7 sched: Track the runnable average on a per-task entity basis
|
||||
```
|
||||
|
||||
当时整个 sched_avg 结构体如下所示:
|
||||
|
||||
```cpp
|
||||
@@ -107,7 +108,7 @@ cfs_rq 上记录的负载信息, 如下所示:
|
||||
|
||||
| 时间 | 特性 | 描述 | 是否合入主线 | 链接 |
|
||||
|:----:|:----:|:---:|:------:|:---:|
|
||||
| 2012/8/23 | [consolidation of CPU capacity and usage](https://lore.kernel.org/patchwork/cover/322242/) | CPU 调频会导致 capacity 的变化, 在支持 DVFS 的系统还用最大 capacity 计算负载是不合理的, 因此 PELT 感知 capacity 的变化 | V1 ☑ 4.1 | [PatchWork](https://lore.kernel.org/patchwork/cover/545867), [lkml](https://lkml.org/lkml/2015/2/27/309) |
|
||||
| 2012/8/23 | [consolidation of CPU capacity and usage](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/log/?id=dfbca41f347997e57048a53755611c8e2d792924) | CPU 调频会导致 CPU capacity 的变化, 在支持 DVFS 的系统还用最大 capacity 计算负载是不合理的, 因此 PELT 感知 capacity 的变化. | v10 ☑ 4.1 | [LORE v10,00/11](https://lore.kernel.org/all/1425052454-25797-1-git-send-email-vincent.guittot@linaro.org), [LKML](https://lkml.org/lkml/2015/2/27/309) |
|
||||
|
||||
|
||||
这组补丁为 PELT 引入了 `frequency scale invariance` 的特性, 当前的系统都是支持 DVFS 的, CPU 处于不同的频率对应的 capacity 肯定是不同的, 特别的对于 big.LITTLE 等架构, 不同 cluster 的能效也是不同的. 因此如果两个相同的进程在不同的频率运行相同的时间, 那么其利用率理论上应该是不一样的.
|
||||
@@ -184,9 +185,9 @@ static __always_inline int __update_entity_runnable_avg(u64 now, int cpu,
|
||||
# 3 PELT 4.3@2015 Rewrite runnable load and utilization average tracking
|
||||
-------
|
||||
|
||||
| 时间 | 特性 | 描述 | 是否合入主线 | 链接 |
|
||||
|:----:|:----:|:---:|:------:|:---:|
|
||||
| 2012/8/23 | [Rewrite runnable load and utilization average tracking](https://lore.kernel.org/patchwork/cover/579066) | 重构组调度的 PELT 跟踪, 在每次更新平均负载的时候, 更新整个 CFS_RQ 的平均负载| v10 ☑4.3 | [LWN](https://lwn.net/Articles/579066), [PatchWork](https://lore.kernel.org/patchwork/cover/590249), [lkml](https://lkml.org/lkml/2015/7/15/159) |
|
||||
| 时间 | 作者 | 特性 | 描述 | 是否合入主线 | 链接 |
|
||||
|:----:|:----:|:---:|:---:|:----------:|:----:|
|
||||
| 2012/8/23 | Yuyang Du <yuyang.du@intel.com> | [Rewrite runnable load and utilization average tracking](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/log/?id=7ea241afbf4924c58d41078599f7a32ba49fb985) | 重构组调度的 PELT 跟踪, 在每次更新平均负载的时候, 更新整个 CFS_RQ 的平均负载 | v10 ☑ 4.3-rc1 | [LWN](https://lwn.net/Articles/579066), [LORE v10,0/7](https://lore.kernel.org/all/1436918682-4971-1-git-send-email-yuyang.du@intel.com/), [lkml](https://lkml.org/lkml/2015/7/15/159) |
|
||||
|
||||
|
||||
在之前的 PELT 实现中, 一次更新只跟新一个调度实体的负载变化, 而没有更新 CFS_RQ 上所有调度实体的负载, 这就导致整个就绪队列上 runnable_load_avg 是失真的. 这组补丁对此做了优化. 在每次更新平均负载的时候, 会更新整个 CFS_RQ 的平均负载.
|
||||
@@ -267,7 +268,7 @@ struct cfs_rq {
|
||||
|
||||
| 时间 | 特性 | 描述 | 是否合入主线 | 链接 |
|
||||
|:----:|:----:|:---:|:------:|:---:|
|
||||
| 2015/8/14 | [Compute capacity invariant load/utilization tracking](https://lore.kernel.org/patchwork/cover/590249) | PELT 支持 Capacity Invariant, 对之前, 对 frequency scale invariance 的进一步优化 | v1 ☑4.4 | [LWN](https://lwn.net/Articles/531853), [PatchWork](https://lore.kernel.org/patchwork/cover/590249), [lkml](https://lkml.org/lkml/2015/8/14/296) |
|
||||
| 2015/8/14 | [Compute capacity invariant load/utilization tracking](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/log/?id=98d8fd8126676f7ba6e133e65b2ca4b17989d32c) | PELT 支持 Capacity Invariant, 对之前, 对 frequency scale invariance 的进一步优化 | v1 ☑4.4 | [LWN](https://lwn.net/Articles/531853), [LORE 0/6](https://lore.kernel.org/patchwork/cover/590249), [LKML](https://lkml.org/lkml/2015/8/14/296) |
|
||||
|
||||
这组补丁 Morten Rasmussen 自打 2014 年就开始推. 当前, 每个实体的负载跟踪仅对利用率跟踪的频率缩放进行补偿. 这个补丁集也扩展了这种补偿, 并增加了计算能力(不同的微架构和/或最大频率/P-state)的不变性. 前者防止在 cpu 以不同频率运行时做出次优负载平衡决策, 而后者确保可以跨 cpu 比较利用率(sched_avg.util_avg), 并且可以直接将利用率与 cpu 容量进行比较, 以确定cpu是否过载.
|
||||
|
||||
@@ -289,11 +290,11 @@ e0f5f3afd2cf sched/fair: Make load tracking frequency scale-invariant
|
||||
|
||||
| 时间 | 作者 | 特性 | 描述 | 是否合入主线 | 链接 |
|
||||
|:----:|:----:|:---:|:---:|:------:|:---:|
|
||||
| 2017/10/19 | Yuyang Du | [sched/fair: Add documentation and optimize `__update_sched_avg()`](https://lore.kernel.org/patchwork/cover/759850) | 异构系统(比如 big.LITTLE) 上通过 DTS 获取 cpu capacity 等信息 | v7 ☑ 4.15 | [PatchWork](https://lore.kernel.org/patchwork/cover/759850) |
|
||||
| 2017/10/19 | Yuyang Du | [sched/fair: Add documentation and optimize `__update_sched_avg()`](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/log/?id=283e2ed3990c36c00403b62b264ebfabaf931104) | 异构系统(比如 big.LITTLE) 上通过 DTS 获取 cpu capacity 等信息 | v7 ☑ 4.15 | [LORE 0/2](https://lore.kernel.org/lkml/1486935863-25251-1-git-send-email-yuyang.du@intel.com) |
|
||||
|
||||
|
||||
```cpp
|
||||
83e2ed3990c sched/fair: Move the PELT constants into a generated header
|
||||
283e2ed3990c sched/fair: Move the PELT constants into a generated header
|
||||
bb0bd044e65c sched/fair: Increase PELT accuracy for small tasks
|
||||
3841cdc31099 sched/fair: Fix comments
|
||||
05296e7535d6 sched/fair: Fix corner case in __accumulate_sum()
|
||||
@@ -337,8 +338,8 @@ Yuyang Du 在 Document 下新增了一个 `sched-pelt.c` 的文件, 用来生成
|
||||
|
||||
| 时间 | 作者 | 特性 | 描述 | 是否合入主线 | 链接 |
|
||||
|:----:|:----:|:---:|:---:|:------:|:---:|
|
||||
| 2016/10/19 | Dietmar Eggemann | [CPUs capacity information for heterogeneous systems](https://lore.kernel.org/patchwork/cover/726135) | 异构系统(比如 big.LITTLE) 上通过 DTS 获取 cpu capacity 等信息 | v7 ☑ 4.15 | [PatchWork](https://lore.kernel.org/patchwork/cover/726135) |
|
||||
| 2017/08/26 | Dietmar Eggemann | [arm, arm64, cpufreq: frequency- and cpu-invariant accounting support for task scheduler](https://lore.kernel.org/patchwork/cover/834799) | 为 ARM/ARM64 提供 FIE/CIE 功能 | v5 ☑ 4.15 | [PatchWork](https://lore.kernel.org/patchwork/cover/834799) |
|
||||
| 2016/10/19 | Dietmar Eggemann | [CPUs capacity information for heterogeneous systems](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/log/?id=be8f185d8af4dbd450023a42a48c6faa8cbcdfe6) | 异构系统(比如 big.LITTLE) 上通过 DTS 获取 cpu capacity 等信息 | v7 ☑ 4.15 | [LORE v7 REPOST 0/9](https://lore.kernel.org/lkml/20161017154650.18779-1-juri.lelli@arm.com/) |
|
||||
| 2017/08/26 | Dietmar Eggemann | [arm, arm64, cpufreq: frequency- and cpu-invariant accounting support for task scheduler](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/log/?id=431ead0ff19b440b1ba25c72d732190b44615cdb) | 为 ARM/ARM64 提供 FIE/CIE 功能 | v5 ☑ 4.15 | [PatchWork](https://lore.kernel.org/lkml/20170926164115.32367-1-dietmar.eggemann@arm.com) |
|
||||
|
||||
|
||||
得益于 ARM big.LITTLE 架构在 ANDROID 的广泛使用, ARM64 是最早支持 FIE 和 CIE 的架构.
|
||||
@@ -358,7 +359,7 @@ Peter 后来进行了一些优化
|
||||
|
||||
| 时间 | 作者 |特性 | 描述 | 是否合入主线 | 链接 |
|
||||
|:----:|:----:|:---:|:--:|:----------:|:----:|
|
||||
| 2016/06/17 | Peter Zijlstra | [sched/fair: Fix PELT wobblies](https://lore.kernel.org/patchwork/cover/690025) | | v1 ☑ 4.8-rc1 | [PatchWork](ttps://lore.kernel.org/patchwok/cover/690025) |
|
||||
| 2016/06/17 | Peter Zijlstra | [sched/fair: Fix PELT wobblies](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/log/?id=7dc603c9028ea5d4354e0e317e8481df99b06d7e) | | v1 ☑ 4.8-rc1 | [PatchWork](https://lore.kernel.org/lkml/20160617120136.064100812@infradead.org) |
|
||||
| 2017/05/04 | Tejun Heo | [sched/fair: Propagate runnable_load_avg independently from load_avg](https://lore.kernel.org/patchwork/patch/785393) | | v1 ☑ 4.15 | [PatchWork](https://lore.kernel.org/patchwork/patch/782955)<br>*-*-*-*-*-*-*-*<br> [PatchWork](https://lore.kernel.org/patchwork/patch/785395) |
|
||||
| 2017/09/01 | Peter Zijlstra | [A bit of a cgroup/PELT overhaul](https://lore.kernel.org/patchwork/cover/827575) | | v2 ☑ 4.15 | 2017/05/12 [PatchWork RFC,00/14](https://lore.kernel.org/patchwork/cover/787364)<br>*-*-*-*-*-*-*-*<br> 2017/09/01 [PatchWork -v2,00/18](https://lore.kernel.org/patchwork/cover/827575), [LKML](https://lkml.org/lkml/2017/9/1/331) |
|
||||
|
||||
|
||||
Reference in new issue
Block a user