diff -u:内核开发中的新内容

作者:Zack Brown

偶尔有人指出 Linux 中存在 POSIX 违规。通常的答案是修复违规行为,但有时 Linus Torvalds 认为 POSIX 行为已损坏,在这种情况下,他们会保留 Linux 行为,但他们可能会构建额外的 POSIX 兼容性层,即使该层速度较慢且效率较低。

这一次,Michael Kerrisk 报告了一个影响文件操作的 POSIX 违规。显然,在多线程操作期间读取和写入文件可能会遇到竞争条件并相互覆盖彼此的更改。

关于这是否真的是违反 POSIX 的行为,存在一些讨论,但最终,谁在乎呢?数据损坏是不好的。在 Michael 发布了一些代码来重现问题后,对话的重点转移到如何修复它。但 Michael 确实提出了一个论点,即“自早期以来,Linux 与 UNIX 并不一致。(例如,1992 年版 Stevens APUE 的第 191 页讨论了 fork() 后父进程和子进程之间文件偏移量的共享。尽管 Stevens 没有明确阐明原子性保证,但如果没有对该保证的推定,那里的讨论将毫无意义。)”

Al Viro 与 Linus 一起试图提出修复方案。Linus 尝试引入一个简单的互斥锁来锁定文件,以便写入操作不会相互覆盖,而 Al 提供了他自己的改进,改进了 Linus 的补丁。

在某个时候,Linus 解释了这个错误本身的历史。显然,曾经有一段时间,文件指针(告诉系统写入文件的位置)被锁定在一个信号量中,因此一次只有一个进程可以对其执行任何操作。但是,他们将其从信号量中取出,以便适应设备文件和其他非常规文件,当用户被禁止在他们愿意时写入它们时,这些文件会遇到竞争条件。

这就是引入错误的原因。当时,它悄悄溜走了,因为对常规文件的实际读取和写入仍然由内核原子性地处理。只有文件指针本身可能会失去同步。而且,由于高速线程文件操作是一种非常罕见的需求,因此花了很长时间才有人遇到问题并报告它。

一个有趣的小细节是,当 Linus 和 Al 正在寻找修复方案时,Al 曾一度抱怨 Linus 采取的方法不支持某些架构,包括 ARMPowerPC。Linus 的回应是,“我怀疑这是否值得关注。[...] 如果 ARM/PPC 人员最终关心,他们可以将 struct-return 支持添加到 gcc。”

总是很有趣地看到角落案例如何出现并得到处理。在某些情况下,部分修复必须在内核中完成,部分在 GCC 中完成,部分在其他地方完成。在这个特定实例中,Al 认为整个事情可以在内核中完成,并且他受到启发编写了自己的补丁版本,Linus 接受了该补丁。

Andi Kleen 想要将低级 CPU 事件支持添加到 perf。问题是可能存在大量的低级事件,并且它因 CPU 而异。即使将所有 CPU 的可能事件存储在内存中也会显着增加内核的运行大小。因此,将此信息硬编码到内核中将是有问题的。

他指出,OProfile 工具依赖于这些事件的公开列表,尽管他说 OProfile 开发人员并不总是将其列表更新到最新的可用版本。

为了解决这些问题,Andi 提交了一个补丁,该补丁允许 perf 识别给定系统上的特定 CPU 需要哪个事件列表,并自动从其主位置下载该列表的最新版本。然后 perf 可以解释该列表并分析事件,而不会给内核带来过重的负担。

对 Andi 的代码有各种反馈,主要是关于哪个目录应该存放事件列表,以及文件名应该是什么。代码本身的行为似乎受到了良好的反响。一个可能比其他细节更具争议的细节是 Andi 决定将列表下载到用户自己主目录的子目录中。Andi 说,否则可能会鼓励用户以 root 用户身份下载事件列表,这将是不良的安全实践。

Sasha Levin 最近发布了一个脚本,用于将堆栈转储中的十六进制偏移量转换为指向内核源文件的有意义的行号。因此,像“ffffffff811f0ec8”这样的内容可能会被转换为“fs/proc/generic.c:445”。

然而,事实证明,Linus Torvalds 计划从堆栈转储中删除十六进制偏移量,原因正是因为它们不可读。因此,Sasha 的代码即将过时。

他们就此来回讨论了一番。起初,Sasha 决定依赖存储在 System.map 文件中的数据进行补偿,但 Linus 指出,包括他在内的一些人并没有保留他们的 System.map 文件。Linus 建议使用 /usr/bin/nm 从编译后的内核文件中提取符号。

因此,似乎 Sasha 的脚本实际上可以为调试堆栈转储提供有意义的文件和行号,假设堆栈转储提供了足够的信息来进行计算。

Zack Brown 是 Linux JournalLinux Magazine 的科技记者,并且是“Kernel Traffic”每周新闻通讯和“Learn Plover”速记打字教程的前作者。他于 1993 年在他的 386 上安装了 Slackware Linux,配备了 8 兆内存,并被开源社区永久性地震撼了。他是 Crumble 纯策略棋盘游戏的发明者,您可以使用一些纸板自己制作。他还喜欢写小说、尝试动画、改革拉班舞谱、设计和缝制自己的衣服、学习法语以及与朋友和家人共度时光。

加载 Disqus 评论