在 Linus Torvalds 发布 Linux 6.16-rc7 测试内核版本之前,今天合并的修复程序中有一个位于“计划/紧急”方面的单独补丁,用于修复可能的虚假负载平均值。内核调度程序代码中报告的系统平均负载可能会从 2021 年 5 月开始出现偏差。
今天早些时候发出
的 sched/urgent pull request 解释了:
“调度程序的单一修复。最近的提交将 runqueue 计数器nr_uninterruptible更改为 unsigned int。由于在将不可中断的任务迁移到其他 CPU 时不会更新计数器,因此这些计数器可能会超过 INT_MAX。在负载平均计算中,计数器被强制转换为 long,这意味着强制转换为负空间,从而导致虚假的负载平均值。将其转换回无符号长以解决此问题。
引入这种潜在虚假负载平均值报告的“最近”提交是 2021 年针对 Linux 5.14 内核的提交。
Oracle 的 Aruna Ramakrishna 追踪了这个问题,并进一步评论了补丁:
“提交 e6fe3f422be1(”sched:使多个运行队列任务计数器成为 32 位“)nr_uninterruptible更改为无符号 int。但是,每个 CPU 运行队列的nr_uninterruptible值可能会增长到很大的数字,有时甚至超过 INT_MAX。如果随着时间的推移,大量任务在进入不可中断状态后从一个 CPU 迁移出去,则这是有效的。只有所有 CPU 上所有nr_interruptible值的总和才能产生正确的结果,如 kernel/sched/loadavg.c 中的注释中所述。
将nr_uninterruptible类型
改回无符号长,以防止溢出,从而导致误判平均负载。
合并代码后,Linus Torvalds 开始评论并质疑为什么代码首先使用无符号值。
将无符号 int 更改为无符号 long 以及将 int 强制转换为 long 的修复现在已合并为 Linux 6.16-rc7。反过来,这也应该在未来几天内向后移植到过去四年支持的 Linux LTS/稳定内核。
转自 Linux 6.16-rc7 Bringing Fix For Possible Bogus/Miscalculated Load Averages – Phoronix
Linuxeden开源社区