标签 内核 下的文章

如果一切顺利的话,周日 Linus Torvalds 将会发布 Linux 5.13 稳定版,而不是发布 5.13-rc8 测试版并把最终版本再推后一个版本。不管是哪种情况,Linux 5.13 很快就会发布,而且会有很多新功能。

在合并窗口结束后,我们照例发布了 Linux 5.13 的功能概述。但是,对于那些不记得在 4 月底到 5 月初的合并窗口期间所有这些变化的人来说,这里回顾了这个下一个内核版本中最突出的变化:


via: https://www.phoronix.com/scan.php?page=news_item&px=Linux-5.13-Features

作者:Michael Larabel 选题:wxy 译者:wxy 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

编者按:本文来自华辰连科技术团队,分享了他们在将浮点运算放到内核态时的探索。

最近我们有一个需求,需要把用户态的浮点数运算全部放到内核态运行,以提高运行速度,移植的过程中发现问题没有这么简单,然后我们抽丝剥茧,揭开 Linux 对浮点处理的原理。

此文章的代码基于 x86 64 位 CPU,Linux 4.14 内核。

一、 Linux 内核添加浮点运算出现的问题

我们以一个简单的浮点运算例子来说明:

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/debugfs.h>
#include <asm/fpu/api.h>
#include <linux/delay.h>

static noinline double float_divide(double float1, double float2)
{
    return float1 / float2;
}

static int __init test_float_init(void)
{
  double result, float1 = 4.9, float2 = 0.49;
​
  result = float_divide(float1, float2);
  printk("result = %d\n", (int)result);
​
  return 0;
}
​
static void __exit test_float_exit(void)
{
  ;
}
​
module_init(test_float_init);
module_exit(test_float_exit);
MODULE_LICENSE("GPL");

test\_float.c

obj-m := test_float.o
KDIR := /lib/modules/$(shell uname -r)/build
​
all:
make -C $(KDIR) M=$(PWD) modules

Makefile

这个内核模块就是计算了两个浮点数除的结果,然后将结果打印出来 。但是我们执行 make 编译的时候发现报错:

提示 SSE 寄存器返回的报错信息为 “SSE disabled”。我们执行 make V=1 查看关键的编译信息:

我们发现在 gcc 的参数中有 -mno-sse -mno-mmx -mno-sse2 选项,原来 gcc 默认的编译选项禁用了 sse、mmx、sse2 等浮点运算指令。

二、通过添加 gcc 编译参数和 kernel\_fpu\_begin/kernel\_fpu\_end 来解决问题

为了让内核支持浮点运算,我们在 Makefile 中添加支持 sse 等选项,源码中添加 kernel_fpu_begin/kernel_fpu_end 函数,修改后的源码如下所示:

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/debugfs.h>
#include <asm/fpu/api.h>
#include <linux/delay.h>

static noinline double float_divide(double float1, double float2)
{
    return float1 / float2;
}

static int __init test_float_init(void)
{
  double result, float1 = 4.9, float2 = 0.49;
​
  kernel_fpu_begin();
  result = float_divide(float1, float2);
  kernel_fpu_end();
  printk("result = %d\n", (int)result);
​
  return 0;
}
​
static void __exit test_float_exit(void)
{
  ;
}
​
module_init(test_float_init);
module_exit(test_float_exit);
MODULE_LICENSE("GPL");

test\_float.c

obj-m := test_float.o
KDIR := /lib/modules/$(shell uname -r)/build
​
FPU_CFLAGS += -mhard-float
FPU_CFLAGS += -msse -msse2
CFLAGS_test_float.o += $(FPU_CFLAGS)
​
all:
make -C $(KDIR) M=$(PWD) modules

Makefile

此时执行 make,发现编译正确通过了:

然后 insmod test_float.ko,观察 dmesg 的输出:

从上面的例子,结合内核源码中 arch/x86/Makefile 中的 KBUILD_CFLAGS,可以看到编译内核及内核模块时,gcc 选项继承 Linux 中的规则,指定了 -mno-sse -mno-mmx -mno-sse2,也就是禁用了 FPU 。所以,要想内核模组支持浮点运算,编译选项需要显式的指定 -msse -msse2

三、 Linux 内核态对浮点运算处理方式的分析

从上面可以看到,我们为了实现一个内核模块的浮点运算,添加了编译参数 -mhard-float和-msse -msse2,对于编译参数来说,-mhard-float 是告诉编译器直接生成浮点运算的指令,而 -msse -msse2 则是告诉编译器可以使用 sse/sse2 指令集来编译代码。

kernel_fpu_beginkernel_fpu_end 也是必须的,因为 Linux 内核为了提高系统的运行速率,在任务上下文切换时,只会保存/恢复普通寄存器的值,并不包括 FPU 浮点寄存器的值,而调用 kernel_fpu_begin 主要作用是关掉系统抢占,浮点计算结束后调用 kernel_fpu_end 开启系统抢占,这使得代码不会被中断,从而安全的进行浮点运算,并且要求这之间的代码不能有休眠或调度操作,另外不得有嵌套的情况出现(将会覆盖原始保存的状态,然后执行 kernel_fpu_end() 最终将恢复错误的 FPU 状态)。

void kernel_fpu_begin(void)
{
  preempt_disable();
  __kernel_fpu_begin();
}

四、三角函数在 Linux 内核态的实现

由于内核态不支持浮点运算,所以像三角函数之类浮点运算都没有实现,如果需要,可以将用户态 glibc 中相关的三角函数的实现移植到内核态。

五、 Linux 用户态对浮点运算处理方式的分析

为什么用户态浮点运算就不需要指定编译选项以及显式调用 kernel_fpu_beginkernel_fpu_end 函数呢?我们在用户态下写一个简单的带浮点运算的例子:

#include <stdio.h>
​
int main(int argc, char **argv)
{
  int result, float1=4.9, float2=0.49;
​
  result = float1 / float2;
  printf("result = %d\n", result);
​
  return 0;
}

user\_float.c

我们分别使用下面四条编译指令查看编译出来的汇编:

  1. gcc -S user_float.c
  2. gcc -S user_float.c -msoft-float
  3. gcc -S user_float.c -mhard-float
  4. gcc -S user_float.c -msoft-float -mno-sse -mno-mmx -mno-sse2

前三条命令编译成功。依次查看编译生成的汇编代码,发现生成的汇编代码是完全一样的,都是用到了 sse 指令中的 mmx 寄存器,也就是使用到了 FPU。

第四条命令编译失败 ,提示 error: SSE register return with SSE disabled。从上面的现象中我们可以得出结论,系统默认使用 gcc 编译用户态程序时,gcc 默认使用 FPU,也就是使用硬浮点来编译。

经过查阅各种文档和分析代码,x86 CPU 提供如下特性:CPU 提供的 TS 寄存器的第三个位是 任务已切换标志 Task Switched bit ,CPU 在每次任务切换时会设置这个位。而且 TS 的这个位被设置时,当进程使用 FPU 指令时 CPU 会产生一个 DNA(Device Not Availabel)异常。Linux 使用此特性,当用户态应用程序进行浮点运算时(SSE 等指令),触发 DNA 异常,同时使用 FPU 专用寄存器和指令来执行浮点数功能,此时 TS_USEDFPU 标志为 1,表示用户态进程使用了 FPU。

void fpu__restore(struct fpu *fpu)
{
  fpu__initialize(fpu);

  /* Avoid __kernel_fpu_begin() right after fpregs_activate() */
  kernel_fpu_disable();
  trace_x86_fpu_before_restore(fpu);
  fpregs_activate(fpu);
  copy_kernel_to_fpregs(&fpu->state);
  trace_x86_fpu_after_restore(fpu);
  kernel_fpu_enable();
}
EXPORT_SYMBOL_GPL(fpu__restore);

假设用户态进程 A 使用到了 FPU 执行浮点运算,此时用户态进程 B 被调度执行,那么当进程 A 被调度出去的时候,内核设置 TS 并调用 fpu__restore 将 FPU 的内容保存。当进程 A 恢复浮点运算执行时,触发 DNA 异常,相应的异常处理程序会恢复 FPU 之前保存的状态。

假设用户态进程 A 使用到了 FPU 执行浮点运算(TS_USEDFPU 标志为 1),此时内核态进程 C 调度并使用 FPU,由于内核只会保存普通的寄存器的值,并不包括 FP 等寄存器的值,所以内核会主动调用 kernel_fpu_begin 函数保存寄存器内容,使用完之后调用 kernel_fpu_end。当用户态进程 A 恢复浮点运算执行时,触发 DNA 异常,相应的异常处理程序会恢复 FPU 寄存器的内容。

六、 结论

  1. Linux 中当任务切换时,缺省不保存浮点器寄存器。
  2. 如果需要内核态支持浮点运算,需要增加支持浮点的编译选项和使用 kernel_fpu_beginkernel_fpu_end 函数手动处理上下文。
  3. 用户态缺省支持浮点运算,但是需要内核来辅助。

LWN.net 发布的 Linux 内核报告中,常年可以看到一个贡献者 —— “Yue Hai Bing”,自 2018 年底以来,TA 对每个版本都会贡献大量的补丁,帮助 Linux 内核不断迭代。为了找到这个来自华为的优秀贡献者,我开始找到朋友圈的华为同学,了解相关信息。每次提到 “Yue Haibing” ,大家都是神秘的一笑,就不再说话。

这让我更加好奇,到底是谁,能如此频繁的在 Linux 内核中贡献,又从未在各种会议聚会中见到 TA?这让我产生了极大的好奇心。直到 openEuler 的问世,我们和 openEuler 社区的合作渐渐变多,终于知道,原来 Yue HaiBing 背后,竟然是华为的自动内核缺陷发现机器人 HULK Robot!正是 HULK Robot 完成了如此高频且优质的内核代码贡献。没想到,我以为的大神,背后竟然是一个机器人!

而为了能够了解到更多关于 HULK Robot 的信息,我采访了 HULK Robot 的架构师 —— 魏勇军先生,和魏勇军先生聊了聊关于 HULK Robot 的故事。

魏勇军(左)接受老王(右)的专访

HULK Robot 的由来

提及 HULK Robot 的诞生,魏勇军提到,其实 HULK Robot 很早便已经在社区应用。在 2017 年的时候,HULK Robot 的前身已经进入到 Linux 内核社区当中,发挥自己的作用。

在当时,HULK Robot 以 “Wei Yongjun” 这个身份,在 Linux 内核社区中贡献代码,提交代码修复补丁。“Wei Yongjun” 提交代码的频率之高,质量之优,让 Linux 内核的核心维护者 Greg Kroah-Hartman 都为之惊叹。在 2017 年北京举办的首次 LC3 大会上,Greg Kroah-Hartman 还专门提到了“Wei Yongjun”。

而来自社区的积极反馈,让魏勇军意识到,这个机器人对 Linux 内核社区是有价值的,可以帮助 Linux 内核越变越好。那为什么不让这个事情更进一步呢?

于是,HULK Robot 正式立项了。

但,说起来容易做起来难。HULK Robot 想要给 Linux 内核贡献代码、提供补丁,却绝非易事。但魏勇军找到了思路。华为多年来虽然在做自己的服务器操作系统,但始终坚持“上游优先”,积累了大量的 Linux 内核维护经验,HULK Robot 可以通过整理过去的华为开发者的经验、测试用例,并将这些进行对比验证,确保这些修改是正确的、有价值的,再将其迁移至 HULK Robot 中,让机器人自动进行更多代码的扫描。

而随着华为对于 Linux 内核的不断进行代码贡献,终于,HULK Robot 成为了一个拥有丰富的测试集和探测能力的机器人。

HULK Robot 如何提交代码?

HULK Robot 随着不断的发展,能够为社区贡献更多的代码,从 Linux 内核的统计报告来看,从 Linux 5.1 开始,一直到最新的 5.10、5.12 ,HULK Robot 的提交能力在逐渐变强,为社区贡献的代码也越来越多, 已经在内核社区历史 Reported-By 榜单排名 TOP2。

魏勇军说,HULK Robot 背后是一套非常复杂的分布式系统。其本质上是一个海量的测试集与一系列先进的自动化测试、问题检测的手段。HULK Robot 和别的 Linux 内核测试机器人不同的是华为因为开发 openEuler 发行版,在内核的维护上付出了不少的时间和精力,拥有丰富的经验,也因此可以在其中贡献更多的代码。

对于魏勇军来说,HULK Robot 如今的重点已经远不是准备更多的测试集,而是要进一步的优化整个内核检测的流程。目前每次版本变更 HULK Robot 都需要跑一次完整的测试集,费时费力,他希望可以让 HULK Robot 可以更加的智能,当代码更改之后,只检测牵涉到相应功能的测试集,而不是测试庞大的全部测试集。此外,加入更多的 DevOps 能力,让更多的人可以参与到 HULK Robot 的开发工作中,更好的为内核贡献代码。这些修改,都可以让 HULK Robot 可以更好的为整个社区提供贡献,更加高效的贡献代码。

也正因为 HULK Robot ,让整个社区可以拥有一个更加稳健和安全的操作系统,整个社区都因 HULK Robot 受益。

社区、开源、机器人

其实一直以来,机器人的应用在开源项目的维护当中是广泛应用的,但对于开源项目本身的维护,一直以来机器人参与的都不多,我也借此机会与魏勇军交流了想法。

魏勇军表示,Linux 内核的维护风格是非常社区化的,社区的维护者默认信任每一个提交贡献者都是为了社区的长期发展而贡献代码,因此,社区的维护者并不拒绝机器人参与到内核的维护中。如果对于整个社区的长期发展是有益的、做出了优质的贡献,社区支持更多的自动化机器人参与到贡献当中。

也许在未来, 我们能看到HULK Robot 会开源,让整个社区一起参与到贡献当中,更好的让 Linux 内核得到维护。

用技术赋能社区

一直以来,Linux 社区都因为资深维护者的流失而担忧,担心社区不再有年轻的血液注入,最终失去了活力。

而 HULK Robot 则为这个事情提供了一种新的思路:可以将资深维护者的经验变成固化的代码,从而使得知识得以传承,而 HULK Robot 的自动化运行机制,又为社区提供了源源不断的贡献和补丁,让这个系统成为一个更加好用和安全的系统。从某种角度来看, HULK Robot 解放了 Linux 内核的贡献者,让贡献者们可以更加专心的做更加重要的事情,把这些繁琐复杂的事情,交给机器人来完成,从而降低了对于社区新鲜血液的需求度。

HULK Robot 不仅仅是为上游提供了新鲜的血液,也更是 openEuler 长期发展不可或缺的护道人,正是 HULK Robot 背后的默默无闻的工作,才能让 openEuler 可以更加稳固的运行,为广大开发者提供一个简单、好用、实用的 Linux 发行版。

我们需要新鲜血液么?当然需要,但如果我们能把门槛降低,这不也是一件好事么?


2021 年 6 月 10 日,openEuler 社区将发起一场面向社区开发者的技术盛会 openEuler Developer Day 2021 ,会上将对多样性计算、云原生全栈、全场景协同等技术发展方向进行持续探索和创新;技术委员会、用户委员会、品牌委员会等 20 个 SIG 组同期举办开放工作会议;技术委员会主席将深入解读 openEuler 21.03,发布下个社区版的技术定位并分享社区创新思路;客户、伙伴、厂商、研究机构将在开源圆桌中共同探讨开源软件供应链的意义和风险,开源模式如何推动以及独立演进操作系统的技术发展。

更多活动信息: https://openeuler.org/zh/interaction/summit-list/devday2021/

推动苹果公司成为万亿公司的一封邮件

2007 年,苹果的市值约为 1500 亿美元。今天,它已经超过了 2 万亿美元,主要是基于 iPhone 的成功,而 iPhone 的成功,至少部分是基于 App Store 的成功。而这一切,都始于乔布斯的一封邮件。

最初,iPhone 在每台设备上只预装了 16 个应用。乔布斯告诉开发者,如果他们想为 iPhone 创造应用,他们可以制作在 Safari 浏览器中运行的网页应用。用户立即开始想办法越狱,以便在他们的设备上安装应用。所以,苹果只能通过某种官方 SDK 使开发应用程序成为可能。乔布斯给该公司软件工程高级副总裁 Bertrand Serlet 回答到:“当然,只要我们能在 2008 年 1 月 15 日的 Macworld 上把它全部推出来。”2008 年,我们见到了苹果的 SDK 和 App Store。

无论主动还是被动,App Store 这种划时代的创举,真正开创了新的智能手机时代。

Linux 内核将一直保留前 1MB 内存

在一些特定的情况下,前 64kb 的内存会被 BIOS 破坏;在另外一些罕见情况下,前面的内存也会被 BIOS 或 EGA/VGA 帧缓冲区所破坏。因此,与其针对不同情况分别设置内存规避区域,不如将整个前 1MB 内存设置为保留。因此,在 5.13 中将永久保留前 1MB 内存而不使用。

现在真是内存富余了,可以随便将 1MB 内存保留不用了。而就在 20 多年前,那时候还是按 KB 计算着使用内存的。

Torvalds 继续反对在编译 Linux 内核时使用 -O3 优化标志

由于 GCC 的较旧版本可能会在 -O3 编译器优化级别下产生坏的代码,而且有时没有性能上的好处,Linus Torvalds 仍然反对在编译 Linux 内核时使用这种优化标志。Torvalds 总结了他目前对 -O3 的看法:“它在历史上一直有可怕的错误。它已经变好了,但‘变好’并不是一个很高的标准。”WireGuard 项目从开始就一直用 -O3 优化级别构建,也并没有看到因此而产生不良代码的情况,但由于 Torvalds 的指导意见,该项目放弃了这个选项。除了 WireGuard 之外,LZ4 和 Zstd 是仍然在用 -O3 的内核模块。

一方面很多厂商转向使用新版本的编译器非常缓慢,另外一方面一些没有那么严谨的代码也并不适合更高级别的优化。理想化的优化措施,在现实情况中往往不能采用。

可能你已经知道原计划支持 2 年的 Linux 5.10 LTS 已经延长支持到 6 年了,但是你可能不知道是谁站出来提供了支持。

支持到 2026 年的 Linux 5.10!

去年年底,Linux 内核社区发布最新长期支持版本 Linux 5.10 LTS 时,该内核只支持到 2022 年 12 月,这让很多社区成员不解,因为发布于 2016 年底的 4.9 版本都支持到 2023 年 1 月。

未延长前的 LTS 支持计划

面对疑问,Linux 内核维护者 Greg Kroah-Hartman 解释说,“我希望看到公司们将如何帮助我测试和维护该内核版本,以使支持它 6 年成为实际可能。”

前不久,我们看到了 Linux 内核社区发布的一则新消息,“在有足够多的公司加强帮助测试之后,Linux 5.10 LTS 现在将维护到 2026 年底。”

发生了什么?在偶然的一个机会,我得知了是谁为 5.10 LTS 承诺了支持。这其中有一家中国公司,这是一家将开源置于战略级高度的公司,我想,你也许已经猜到了,是华为

说实话,听到这个消息时,既有些意外也不意外。意外的是,我没想到中国开发者和 IT 企业已经在承担这样的重任了;不意外的是,毕竟华为已经是全球首屈一指的 Linux 内核贡献大厂了,就在 Linux 5.10 中,华为以提交 1434 个补丁而位列内核代码贡献第一名,同时以代码修改行数 41049 行位列第二名。

Linux 5.10 贡献排行榜,华为名列榜首

可能作为普通用户并不关心使用的是不是 Linux,更不关心使用的是什么版本和有多久的支持期,但作为一家专注于 Linux 与开源的技术社区,我深刻理解其中的含义,也更关心华为在做出这样的决定背后的考虑、付出和可持续性。于是,我和 Linux ARM64 ACPI Maintainer、openEuler Maintainer、华为工程师郭寒军约了一个访谈,现在将其中主要内容分享给诸位读者。

为 LTS 提供支持

杭州的梅雨季显得并不炎热,在一间很大的房间中,我和看起来比我年轻多了的受访者郭寒军同学进行了一段简短而精炼的对话。

郭寒军(左)接受老王(右)的专访

首先,我直奔主题问到了为什么华为会做出对 5.10 LTS 支持的承诺?从事了 Linux 内核开发十余年的郭寒军很有技术人员本色,他坦诚说,“华为将 Linux 内核用于各种各样的产品。我们在 Linux 内核上积累了很多经验,包括开发、测试和维护的能力。我们觉得可以做这些支持。”在华为内部进行了简单的讨论,讨论了需要投入的机器的资源、人的资源等等。在资源协调到位之后,“我们就公开地在邮件列表上向 Linux 内核社区与 Greg 表态说,我们愿意从公司的角度协助做维护和测试工作。”

据我所知,Linux 5.10 LTS 也将是 Debian 11 和安卓的下一个版本的内核,而在一众已经或即将采用 Linux 5.10 LTS 的软件或产品中,openEuler 发行版家族并不是最引人注目的一个,但是华为却是最主动站出来的一个。当然,在华为的表态带动之下,也有更多企业参与到了 LTS 的支持工作当中。

郭寒军还说,“其实我们提供支持的不仅仅是 Linux 5.10 LTS,而是会对目前较新的 4 个 LTS 内核都提供支持,并且会持续支持更多的 LTS 内核。”这又是一个令我意外的事情。作为一位从业互联网软件开发二十多年,眼看着 Linux 内核从一张低密度软盘即可承载的软件变成了世界上最大的软件项目,我深知要支持现在这么庞大的软件项目背后的代价有多大。其实,之所以 Greg 在一开始给 Linux 5.10 LTS 只计划了 2 年的支持期,就是因为 Linux 内核社区已经积累了 6 个 LTS 支持版本,在支持力量上有些力不从心了。目前,Linux 稳定内核的维护负责人只有两位 Greg Kroah-Hartman 和 Sasha Levin,可想而知,仅仅两人是很难照顾这么多的 LTS 内核维护工作的。

据我了解,华为对 Linux LTS 内核的测试用例已经有 8000 多项,而且还支持包括 x86\_64、ARM64 等多种架构,每个版本的测试就需要 7-8 个小时,这就需要投入大量的基础设施。

当然,我想华为在 Linux 内核方面的偌大投入,绝非是一时心血来潮,也不仅仅是技术极客们的热情奉献所致。这个支持决定不仅符合华为整体的开源战略,也给鲲鹏和 openEuler 等提供了一个坚实的底座。

内核能力对云原生社区的重要性

Linux 内核是整个系统的底座。所有的上层的技术,包括其上的一些应用软件都是构建在内核上面的。内核的稳定性、性能以及内核的后续的技术创新方向,都会对整个 Linux 生态和社区产生重要影响。这就是为什么我们要花这么多精力去保证它的稳定性,也是为什么要主动去承担 Linux LTS 支持的原因。

为了打造这样的一个底座,华为在内核方面进行了长期而卓有成效的投入,并把在内核方面的积累在 openEuler 社区开放。郭寒军认为 openEuler 在内核方面的能力主要体现在三个方面:兼容性、性能提升和创新。

从兼容性来说,这包括 CPU 架构和硬件的兼容性。除了支持 ARM64 架构的鲲鹏、飞腾处理器之外,openEuler 还可以支持 x86\_64 架构的兆芯、英特尔、AMD 等 CPU 架构,以及 RISC-V 家族。

从性能提升方面来说,openEuler 的多核并行等技术,针对调度机制、CPU 资源管控等来提升整个业务的线性度以提升性能。这些技术已经通过 openEuler 的下游发行版提供给了更多行业用户,真正使社区和行业用户受惠于软件技术带来的全新使用体验。

从创新方面来说,openEuler 内核的创新包括:

  • 第一个创新是文件系统方面的。文件系统是华为的强项之一,从可扩展只读文件系统 EROFS 到基于非易失性内存的新型文件系统,随着存储技术的发展,也需要有新型的文件系统做支撑。
  • 第二个创新是弹性软内存。这是指如何有效的利用不同速度和不同容量的存储系统,做一些分级控制,既能使用到大容量的存储,而又不降低性能。
  • 第三个是目前正在重点打造的云原生内核。在云原生内核方面,业界已经有了一些探索,而华为可以结合其硬件能力做全栈的云原生支持,从进程的调度,到内存、网络以及存储,再到最底层的硬件,提供一个 QoS 控制来支持高优先级任务。

openEuler 对 Linux 生态的意义

自 2019 年 12月 31 日 openEuler 开源以来,已有 70多家企业、机构和组织加入了 openEuler 社区,4700 多位社区开发者,成立了 83个 SIG,并有 8 家合作伙伴推出基于 openEuler 的商业发行版,在金融、政府、运营商和电力等各行业得到了广泛商用。而在去年,openEuler 社区理事会正式成立、技术委员会升级;今年,又新成立了用户委员会和品牌宣传委员会,社区治理逐步完善,走向“共建、共享、共治”。

对此,郭寒军认为,建立在 openEuler 下游的发行版天然会具备一些优势。华为一直坚持并倡导“上游优先”原则,积极地将其对 Linux 内核的改进推送到上游 Linux 内核主线,但是基于内核社区的运作机制,这个过程必然是较为漫长和复杂的。因此,openEuler 开源社区拥有的强大的 Linux 内核能力,对 openEuler 及下游的发行版来说,可以更快的响应一些特定的功能需求和硬件支持。这对于国内的一些硬件厂商来说尤为重要,可以统合更多的力量而做到更广泛的支持。

结语

作为一家迅速崛起的 Linux 生态开源社区,openEuler 所取得的进展令人侧目。一两年间,openEuler 及其背后的华为、麒麟、统信、联通数科、中科院软件所等一批企业,已经在整个 Linux 生态、云原生领域取得了长足发展。而在企业战略级的支持下, openEuler 社区所回哺给 Linux 社区的也足以令人赞叹,这让我对开源、对中国开源的未来有更多信心。

正如我们昨天报道的,明尼苏达大学的研究人员被踢出了 Linux 贡献群体,Linux 内核社区撤销了之前他们提交的所有 Linux 内核代码,并且,以后默认拒绝所有来自该大学的内核贡献!

发生了什么?是什么让 Linux 内核社区勃然大怒?

这一切始于 2021 年 4 月 6 日对 Linux 内核的一个看似无辜的补丁。明尼苏达大学的一名博士生(Aditya Pakki)提交了一个一共只修改/增加了两行的小补丁

Signed-off-by: Aditya Pakki <[email protected]>
---
 net/rds/message.c | 1 +
 net/rds/send.c    | 2 +-
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/net/rds/message.c b/net/rds/message.c
index 071a261fdaab..90ebcfe5fe3b 100644
--- a/net/rds/message.c
+++ b/net/rds/message.c
@@ -180,6 +180,7 @@ void rds_message_put(struct rds_message *rm)
         rds_message_purge(rm);
 
         kfree(rm);
+        rm = NULL;
     }
 }
 EXPORT_SYMBOL_GPL(rds_message_put);
diff --git a/net/rds/send.c b/net/rds/send.c
index 985d0b7713ac..fe5264b9d4b3 100644
--- a/net/rds/send.c
+++ b/net/rds/send.c
@@ -665,7 +665,7 @@ static void rds_send_remove_from_sock(struct list_head *messages, int status)
 unlock_and_drop:
         spin_unlock_irqrestore(&rm->m_rs_lock, flags);
         rds_message_put(rm);
-        if (was_on_sock)
+        if (was_on_sock && rm)
             rds_message_put(rm);
     }
 

由于这个补丁很简单,而且似乎改善了代码的质量,它最初得到了一些成员的支持,但后来在 4 月 9 日受到了 Eric Dumazet 的质疑

而在 4 月 19 日,资深的内核贡献者 Al Viro 斥责该贡献者提交了一个“没有修复任何东西的补丁”。他指出了提交垃圾代码补丁的两种可能性:

简单地说,这个补丁要么显示出完全缺乏理解,要么显示出有人不真诚地行事。如果是后者[1],我可以建议尊敬的社会学家们滚蛋,不要再用故意喷出的排泄物来测试审核者了?

如果你觉得他用词太激烈了,这背后是有原因和历史的。

前不久,明尼苏达大学的博士生 Qiushi Wu 和助理教授 Kangjie Lu(看起来是中国人或华裔?)提交了一篇研究论文《论通过伪装提交在开源软件中隐蔽地引入漏洞的可行性》。据之前发布在明尼苏达大学的一篇新闻稿(已被删除),该论文被 2021 年 IEEE 安全与隐私研讨会接受:

CS&E 很荣幸地与大家分享博士生 Qiushi Wu 和助理教授 Kangjie Lu 为即将举行的第 42 届 IEEE 安全与隐私研讨会所撰写的论文。IEEE S&P 是展示计算机安全和电子隐私发展的首要论坛,并将该领域的研究人员和从业人员聚集在一起。

他们的论文《论通过伪装提交在开源软件中隐蔽地引入漏洞的可行性》集中讨论了开源软件的供应链安全。

“这项工作影响深远,”Lu 教授说,“供应链安全已经成为当今的一个重要话题。我们的论文已经引起了安全界和开源社区的极大兴趣。”

Wu 和 Lu 将在 5 月的虚拟会议期间展示他们的研究。

研究人员正在测试通过伪装提交在开源软件中隐蔽引入漏洞的可行性,也就是说,以看似有益的提交实际上引入了其他关键问题。结合最近发生的一些软件供应链攻击事件,看起来这是一篇很有意义的论文,也难怪会被 IEEE 会议接受。

然而,似乎他们选择了 Linux 内核项目来进行他们的实验来完成论文。Al Viro 发现,Aditya Pakki 的“无用补丁”很可能是这项研究的一部分。

对 Aditya Pakki 提交的另外一个补丁

     }
-    gss_release_msg(gss_msg);
+    if (gss_msg)
+        gss_release_msg(gss_msg);
 }

GKH 警告称,不要浪费内核维护者的时间提交这种补丁,Greg Kroah-Hartman(GKH)是仅次于 Linus Torvalds 的内核项目负责人:

请停止提交已知无效的补丁。你的教授正在玩弄审查程序,以便用一些奇怪的、怪异的方式实现一篇论文。
这是不对的,这是在浪费我们的时间,我们将不得不再次向你的大学报告此事……

显然,这不是唯一引起争议的补丁请求。而 Leon Romanovsky 指出,还有 3 个这样的补丁来自同一个研究人员,并认为这些补丁增加了安全漏洞:

他们故意引入内核错误。昨天,我看了一下从 Aditya 那里接受的 4 个补丁,其中 3 个增加了各种严重的安全 “漏洞”。

面对这些公开抨击,该大学的研究人员 Aditya Pakki 认为自己是受害者,指责内核维护者的态度

敬请停止胡乱指责,这近乎诽谤。

这些补丁是作为我写的一个新的静态分析器的一部分发送的,它的灵敏度显然不是很高。我发送补丁的目的是希望得到反馈。我们不是 Linux 内核方面的专家,反复发表这些言论让人听了很反感。

显然,这一步错了,但你的先入为主的偏见是如此强烈,你提出的指控毫无根据,这种怀疑也不会带来任何好处。

这种态度不仅让人讨厌,而且对新手和非专家也是一种恐吓,我再也不会发送任何补丁了。

这激怒了 GKH,他说:

你和你的团队,已经公开承认发送了有缺陷的补丁,以了解内核社区对它们的反应,并且发表了一篇基于这项工作的论文。现在你又提交了一系列新的有明显错误的补丁,那么我应该对这样的事情怎么看?

它们显然不是由一个有智慧的静态分析工具创建的,因为它们都是完全不同的模式的结果,而且所有这些显然根本没有修复任何东西。 那么,除了你和你的团队在继续通过发送这种无稽之谈的补丁对内核社区的开发者进行试验之外,我还能想到什么?

……

任何有 C 语言知识的人,只要花几分钟就能看出你提交的文件根本没有任何作用,所以认为一个工具创造了它们,然后你认为它们是一个有效的“修复”,这完全是你的疏忽,而不是我们的疏忽。你才是有错的人,我们的工作不是成为你创造的工具的测试对象。

……

我们的社区不喜欢被实验,也不喜欢通过提交已知的补丁来“测试”,这些补丁要么是故意什么都不做,要么是故意引入错误的。 如果你想做这样的工作,我建议你找一个不同的社区来进行你的实验,这里不欢迎你。

正因为如此,我现在不得不禁止你的大学今后的所有贡献,并撕掉你以前的贡献,因为它们显然是以恶意的方式提交的,目的就是为了造成问题。

随后,GKH 撤销了明尼苏达大学提交的大量补丁,GKH 表示:

我一直想这么做,但最近的事件终于迫使我这么做了。

……

这个小组提交的所有文件都必须从内核树上撤销,并需要再次进行审查,以确定它们是否真的是一个有效的修复。 在这项工作完成之前,请删除这些变更,以确保没有问题被引入代码库。

这个补丁集包含了“简单”的修正,还有 68 个需要人工审查的修正。 其中一些不能被恢复,因为它们已经被恢复了,或者被确定其为无效的后续补丁所修复。这证明这些提交的文件几乎都是错误的。

我将和其他一些内核开发者一起工作,以确定这些还原是否真的是有效的变更,如果是的话,以后会重新正确提交。就目前而言,还是安全为上。

我将通过我的开发树进行,所以维护者们不需要担心这个问题,但他们应该意识到,未来任何从 umn.edu 地址来的人提交的文件应该被默认拒绝,除非确定它实际上是一个有效的修复(即他们提供证据,你可以验证它,但是说真的,为什么要浪费你的时间做那些额外的工作?)

对此,你怎么看?

本文参考信息: lore.kernel.org、news.itsfoss.com。