跳到主要内容

每周一龙:第 23 期

· 阅读需 13 分钟
WANG Xuerui
🐲龙门客栈打杂的

每周一都为大家报道 LoongArch 社区最前线的第一手新鲜资讯! 上周的进展主要有 LoongArch ABI v2.20、Linux、GCC 以及 LLVM。 详情点进来看!

如无特别说明,文中提及的日期、时间都为北京时间(UTC+8)。

先「马」再看

本栏目的内容具有一定延续性,将持续追踪报道 LoongArch 领域的重要或长期项目(坑)。

Linux

上期我们用较大的篇幅报道了 LoongArch v1.10 的新增特性。 因此虽然 Linux 6.6 也在上周正式发布了,但我们并未马上详细报道。 截至目前,Linux 6.7 的合并窗口仍在火热开放中,而龙架构的变更相对不多; 我们可以先把上周的 Linux 6.6 内容补上,再简单过一遍本周期的新功能。

Linux 6.6

我们在周报第 14 期整理过了 Linux 6.6 的龙架构相关变更,可方便跳转阅读。

除此之外值得一提的是:从该版本开始,Linux 的默认调度算法被重做了, 从 CFS(completely fair scheduler;完全公平调度器) 变为了上世纪九十年代一篇论文提出的 EEVDF(earliest eligible virtual deadline first;最早到期的虚拟截止时刻优先),LWN 对此做了讲解。 该改造由著名 Linux 调度器维护者 Peter Zijlstra 操刀。

经社区测试,EEVDF 调度算法能以更少的配置项,在大多数场景下实现更高的公平性与吞吐; 显然,CFS 并不「完全公平」,尽管它确实也比它的前任 O(1) 调度器更公平些。 但也不排除个别场景由于受益于先前 CFS 算法的不公平,而在新内核反而性能劣化,像是受了 EEVDF 惩罚一样。 请那些需要或者已经迫近系统性能极限的开发者和用户们注意:升级内核前重新跑跑压测。

除以上变更之外,还有许多同等重要的缺陷修复、代码重构等工作值得褒扬。 这个版本动过龙芯相关代码的所有开发者们(按字母顺序排序,以 Git 提交记录中的作者字段为准):

  • Andy Shevchenko
  • Aneesh Kumar K.V
  • Baoquan He
  • Bibo Mao
  • Binbin Zhou
  • Costa Shulyupin
  • Dan Carpenter
  • Enze Li
  • Eric DeVolder
  • Feiyang Chen
  • Helge Deller
  • Hongchen Zhang
  • Huacai Chen
  • Icenowy Zheng
  • Jiri Slaby
  • Keguang Zhang
  • Maciej W. Rozycki
  • Matthew Wilcox (Oracle)
  • Mingtong Bao
  • Nathan Chancellor
  • Nick Desaulniers
  • Paul E. McKenney
  • Qi Hu
  • Qing Zhang
  • Russell King (Oracle)
  • Sui Jingfeng
  • Thomas Zimmermann
  • Tiezhu Yang
  • Tom Rix
  • Vishal Moola (Oracle)
  • WANG Xuerui
  • Weihao Li
  • Yanteng Si
  • Yinbo Zhu
  • YingKun Meng
  • Zhangjin Wu

这些维护工作涵盖了 MIPS 和龙架构两个时代的龙芯 CPU,以及架构无关的大量龙芯平台外设驱动。 当你在龙芯硬件上使用 Linux 6.6 时,别忘了向 们说声谢谢!

信息

本节报道的信息可以通过简单的 git 操作从 Linux 仓库中获取:

git log --no-merges -P --grep='(?<!: |@)[Ll]oong' v6.5..v6.6

Linux 6.7

截至发稿时,LoongArch 的 KVM 支持已经进入主线了。 按照 Git 提交信息,此工作主要是由 Tianrui Zhao、Bibo Mao、Huacai Chen 几位同学协同完成的; 当然,可能也有些没署名的无名英雄。 恭喜 们!

目前 loongarch-next 分支只有一个新提交:10 月 30 日 Huacai Chen 给龙架构加上了支持动态抢占的标记。

11 月 2 日,Nathan Chancellor 在 ClangBuiltLinux 项目日常维护中, 帮忙完善了 LoongArch percpu 辅助函数的内联标记:由于近日 LLVM 优化方面的变动,有的这方面函数调用不再被内联了。 这是非预期的:这些函数必须被内联才能正常工作。 因此正确做法就是将它们标记为总是内联(在 Linux 里 __always_inline 这么写)。

以上的内容估计都会在本周晚些时候进入主线,赶上 Linux v6.7-rc1 的火车。

工具链

ABI

11 月 4 日,龙芯工具链团队将 LoongArch ABI 规范文档更新到了整体版本 v2.20。

其中,ELF psABI 子文档的版本号更新到了 20231102,相比 20230519 版本:

  • 新增了表示过程调用,跳转范围 ±38 位的重定位类型 R_LARCH_CALL36

    由于跳转目标必须对齐到 4 字节,jirl 指令会自己给它的立即数左移两位, 因此实际有效数字只有 36 位,故名。

    这也是龙架构首个同时作用于两条指令的 ELF 重定位类型: 该类型的重定位记录必须被附着于连续的两条 pcaddu18i & jirl 的第一条,才能正常工作。

    此设计解决了 2022 年 9 月 xry111 发现的坑点(后由 笔者转发到当前所用的文档仓库)。

  • 移除了压根不可能用起来的 R_LARCH_DELETER_LARCH_CFA 两种重定位类型;其编号暂时保留,不挪作他用。 这是采纳了笔者 6 月份的建议

  • 修正了表格中的复制粘贴笔误:R_LARCH_SUB_ULEB128 名字错了。

主编评论

关于 R_LARCH_CALL36: 没有采用会暴露 pcaddu18ipcalau12i 本质不同的设计提议。

虽然重定位处理的纯洁性已经无法恢复:

  • 以前没有这玩意时候,已经实装了「给立即数宽 16 位还自带左移 2 位的 jirlR_LARCH_PCALA_LO12 这个正常只往不同位域写低 12 位还不做右移处理的记录」这个 workaround, 导致需要实现 workaround 语义才能正常链接的目标代码早就遍地都是,没法消除了。
  • 此外,LoongArch v1.10 也没有添加当时呼吁的 pcalau18i 以便链接器不用带「PC-relative」 跟「PC-aligned」两套迥异的计算逻辑——优雅不能当饭吃。

但至少此设计满足传达语义的需要,其对相关指令必须相邻的要求也对硬件实现非常友好,因而笔者认为仍然是良好的设计。

关于 R_LARCH_DELETE:这大概是先前做 linker relaxation 时候,没有仔细区分 BFD 实现细节导致的。 观察 RISC-V 相似名字的 R_RISCV_DELETE 定义: 被明确定义为 BFD 实现细节,不放置于公开的头文件,且在文档上显著说明了。 对龙架构工作者而言,也算是积累经验了吧!

此外,《LoongArch 过程调用约定》子文档的版本号更新到了 20231103, 相比 20230519 版本主要是明确了围绕宽度为零的量的处理细节;此外也微调了一些措辞。

主编评论

这都是几个月来同学们在各大上游社区仔细讨论的成果。 差点就要为这些纯粹起标记作用,不该占地的字段浪费寄存器了! 感谢上游多位 C++ 大师出手相助,给我们讲清楚 C/C++ 规范里那些文字资料鲜少涉及,课上更不可能讲的边界情况。

gcc

11 月 3 日,Chenghui Pan 修了一处笔误: 有个 vldi 之前给写成 ldi 了。 之前没测出来!

11 月 2 日,GCC 贡献者 Vladimir Makarov 反馈说近两周间 改进了 GCC 的寄存器分配算法,修复了在 LoongArch 等若干架构出现毫无意义的寄存器保存指令的问题。 感谢 xry111 提供新闻线索和新闻稿!

两三周前,笔者的 GCC 14 就无法自举了,踩上了 binutils linker relaxation 的坑; 不过在笔者找到时间写 bug 报告并上报之前, 五天前,专攻 GNU 工具链的 xry111 也被坑到了,并且在上游建立了这个 bug。 目前的发现是只要搭配最新 binutils 就会自举失败,体现为汇编器或者链接器崩溃(视你拣取的后续修复提交多少而不定); 但在 gcc r14-5075 这个提交之后,问题又神奇般地暂时消失了。 问题的根因尚未找到,同学们仍在努力。 感谢 xry111 提供新闻线索!

LLVM

与前面报道的 LoongArch ABI 文档修订有些相关,上周有两处 Clang 与 GCC 对 ABI 的理解差异得到了修复。

  • issue #70319: 由 Ami-zhang 两周前报告,由 SixWeining 在 #70320 修复;事关空 struct
  • issue #70890: 由 SixWeining 五天前报告,随后在 #71025 自己修复;事关空 union

此外,11 月 4 日 zhaoqi5 给龙架构的 MC(机器代码)组件添加了围绕 jirl 指令的额外逻辑,让它更聪明了。 根据提交说明中透露的消息,龙芯已经在着手移植 LLVM BOLT 到龙架构了。 这位同学似乎也是首次在上游公开露面;欢迎欢迎!

BOLT 是啥?

BOLT 是最早由 Facebook(现 Meta)团队创造,之后贡献给 LLVM 项目的一款二进制优化器。 只要喂给它带有重定位信息的成品二进制程序,以及实际运行中收集的代码段热度信息; 不要源代码,它就能优化这个输入程序的代码布局,从而不改一行代码轻松提升性能。 这对使用编译型语言的大小厂都非常有用。 详见 BOLT 项目 README

张贴栏

本栏目可供张贴公益性质的各种信息。

  • 友情扩散:安同开源社区(AOSC)的龙架构移植主线化工作「合龙」仍在如火如荼进行中, 此工作完成后龙架构将升格为 AOSC OS 的 Tier 1 架构。 欢迎同学们试用、反馈,也欢迎有志之士一同加入(沟通渠道详见 AOSC 网站相关栏目)。
  • 本周报持续接受网友投稿。欢迎来上游坐坐!