关注了就能看到更多这么棒的文章哦~

How to cope with hardware-poisoned page-cache pages

By Jonathan Corbet
May 5, 2022
LSFMM
DeepL assisted translation
https://lwn.net/Articles/893565/

"hardware poisoning" 是一种检测和处理运行系统中出现内存错误的机制。当某一段内存区域内内容不再正确时,它就是 "中毒(poisoned)" 了,对这个区域的后续访问将产生错误。内核对 hardware poisoning 的支持已超过十年,但这并不意味着它就不需要改进了。在 2022 年的 Linux 存储、文件系统、内存管理和 BPF 峰会上,Yang Shi 讨论了当 hardware poisoning 影响到 page cache 所有的内存时该如何处理的问题。

page cache 中存放着后备存储中的文件的一部分 page 的副本。如果 page cache page 产生错误不再能准确地反映文件中的数据,就不应该再被使用了。如果该 page 在从后备存储中读取后就没有被修改过,那么解决方法很简单,直接丢弃然后将数据重新读入能正常工作的内存区域。但是,如果该 page 是 dirty 状态的(被 CPU 写入过),情况就更难处理了。Shi 说,目前该 page 会被从 page cache 中删除,其中的数据都会丢失。除非进程将受影响的 page 映射到了他们的地址空间,否则进程就不会收到通知。

Shi 说,这种行为会导致数据默默地就丢失了。随后对该 page 的访问将产生不正确的数据,而用户却不知道这里出现了问题。这就导致了一些很难 debug 的问题。

为了解决这个问题,他继续说,内核应该把中毒的 page 保留在 page cache 中,而不是丢弃掉。需要把这个问题告知拥有该 page 的文件系统,并且不能尝试将该 page 写回后备存储里。有些操作,如 truncate 或 hole-punching 可以继续允许正常使用,因为相关结果应该是正确的。但如果以其他方式访问该 page 的话必须返回一个错误。

有几种方法可以实现这种行为。一种是在每个访问 page cache 的 page 的路径上检查 hardware-poison flag,这将需要修改大量的代码。另一种方法是,在 cache 中查找 page 时返回 NULL。这样做的好处是,调用者已经能够处理 NULL 的返回值,所以应该不会感到意外,只是返回的错误代码会是 ENOMEM,这可能会让人感到吃惊或误解。最后,page cache 的查找(lookup)动作可以改为返回 EIO,这能更好地表明真正的问题来自哪里。不过,这个改动会有更大的影响,因为调用者没有准备好处理这种返回状态。

Matthew Wilcox 跳出来说,只有第一个选择才是真正可行的方案。poison 问题是按 page 来追踪的,但更高层级的接口正在被转换为 folio,其中可以包含多个 page。一个 folio 中未被破坏的部分应该仍然可以被访问到,所以 page cache 的 lookup 机制需要能保持正常工作。Dan Williams 说,在 DAX 代码中(实现 persistent memory 中的文件的 direct access),他所采取的方法是将错误告知文件系统,并仍然从 page cache 中删除掉该 page。他说,这样就可能给用户返回错误了;这可能也是处理普通内存设备中的错误的一个好方法。

Ted Ts'o 同意 Williams 的观点,他说,如果关于一个损坏的 page 的信息只存在于内存中,那么系统 crash 的时候就会导致这些信息都丢失了,这也会导致相应的数据损坏无人知道。他说,这里提出的解决方案做了大量的工作,只在下一次重启发生之前返回 EIO。还需要文件系统这边做更多工作来维护这些信息,但最终来看可能是更好的方法。他说,有一种方法可以使其更容易,那就是不用关心逐个追踪损坏的 page;相反,可以给文件标记一下它其中有的地方已经损坏了。

Shi 认为,在大型数据中心环境中,内存故障并不是特别罕见的现象,而且他的两种方法任何一种都比什么都不做要好。另外,他说,用户很可能关心文件中的哪一个 page 被损坏了,所以仅仅把文件作为一个整体来标记可能是不够的。

Kent Overstreet 说,除了向用户返回出现问题的标志信息外,这项工作的重点是要避免向磁盘写回垃圾数据。然后,如果系统崩溃,"石板就被擦拭干净了",损坏的内存不再存在。他说,crash 其实可能是最好的情况。Wilcox 回答说,这种 "最好的情况" 也仍然会导致数据损失。

Josef Bacik 说,存储损坏了的数据,对他来说是最有意义的;具体实现方法主要是在通用的文件系统代码中。当被告知有问题时,文件系统代码应该标记出受到影响的 page,拒绝从这些 page 返回任何数据,并注意避免将它们写入后备存储。但他建议,每个文件有一个标志可能就足够了。开发人员(包括用户空间的和内核空间的)全部都不擅长处理错误场景,所以这个机制应该保持简单,特别是在最开始的时候。开发人员可以在以后 "尝试更加花哨的方法",如果看起来确实有必要的话。

David Hildenbrand 反对说,每个文件一个标志的话可能会阻碍虚拟机从存储在单一文件中的镜像来运行。这种情况一个错误就会阻止整个文件的使用了,基本上就会导致虚拟机被 kill。能追踪单个 page 的话可能更适合于这种使用情况。但 Bacik 重申,社区人员一定会写出错误的代码,所以应该先做尽量简单的案例。

随着时间的推移,Wilcox 指出,文件系统可以处理向一个损坏的 page 写入的情况,如果整个 page 都被覆盖的话。在这种情况下,损坏的数据就消失了,而文件又一次处于用户预期的状态了。不过,Goldwyn Rodrigues 指出,对于 copy-on-write 的文件系统来说,情况并不那么简单,它们可能仍然有损坏的 page 在那里。Bacik 说,这种情况正是他反对花哨的解决方案的原因。

全文完
LWN 文章遵循 CC BY-SA 4.0 许可协议。

欢迎分享、转载及基于现有协议再创作~

长按下面二维码关注,关注 LWN 深度文章以及开源社区的各种新近言论~

LWN:如何处理硬件出错导致的错误page-cache page?相关推荐

  1. Linux的Page Cache

    1. Page Cache 何为Page Cache 为了了解Page Cache我们可以看一下Linux的文件I/O系统 从图中可以看出,Page Cache是由Linux内核进行管理的,而且通过m ...

  2. linux那些事之page cache

    page cache page cache又称高速缓存,主要是针对文件文件系统,为了减少不必要的磁盘IO操作(读/写)造成卡顿问题,内核将磁盘文件中的内容缓存到内存中,并选择适当时机对磁盘进行读写操作 ...

  3. 和linux关系_Linux内核Page Cache和Buffer Cache关系及演化历史

    在我们进行数据持久化,对文件内容进行落盘处理时,我们时常会使用fsync操作,该操作会将文件关联的脏页(dirty page)数据(实际文件内容及元数据信息)一同写回磁盘.这里提到的脏页(dirty ...

  4. linux刷新磁盘_Linux内核Page Cache和Buffer Cache关系及演化历史

    在我们进行数据持久化,对文件内容进行落盘处理时,我们时常会使用fsync操作,该操作会将文件关联的脏页(dirty page)数据(实际文件内容及元数据信息)一同写回磁盘.这里提到的脏页(dirty ...

  5. linux page cache 大小,Linux内核学习笔记(八)Page Cache与Page回写

    Page cache是通过将磁盘中的数据缓存到内存中,从而减少磁盘I/O操作,从而提高性能.此外,还要确保在page cache中的数据更改时能够被同步到磁盘上,后者被称为page回写(page wr ...

  6. 页面缓存导致数据错误

    页面缓存导致数据错误 服务端渲染(ssr)会将 API 数据做页面元素返回给前端, 而浏览器会认为是静态页面并将页面缓存, 导致每次访问时都是缓存用户数据. 页面又包含对数据的处理并提交. 当多端更新 ...

  7. Visual Studio2012打开时弹出“遇到异常:这可能是由某个扩展导致的”错误的解决办法...

    Visual Studio2012打开时弹出"遇到异常:这可能是由某个扩展导致的"错误的解决办法: 具体问题如下: 分析原因:网上搜集了以下,出现异常的原因是安装了第三方控件,然后 ...

  8. 超融合硬件损坏导致Oracle RAC异常恢复实录

    墨墨导读:一套Oracle RAC环境运行在HW超融合环境中,由于硬件问题导致数据库crash,期间出现了不少数据坏块,本文详述整个恢复过程,希望对大家有帮助. 前几天某客户遇到一个棘手问题:其一套O ...

  9. 产品硬件成本分析_硬件项目中的错误成本

    产品硬件成本分析 Hello everyone! 大家好! In this article, we will consider common errors in the design of elect ...

最新文章

  1. 使用PlanAhead查看Virtex-7系列FPGA的底层架构
  2. CSP认证201512-2 消除类游戏[C++题解]:模拟
  3. eclipse中不能找到dubbo.xsd解决方法
  4. Python中最长公共前缀
  5. 【Luogu】P3369 【模板】普通平衡树(树状数组)
  6. Android与Swift iOS开发:语言与框架对比
  7. “【第二届】Erlang Fans交流会”议程
  8. Android NDK--自己编写调用JNI
  9. 03 unix 设计哲学和流重定向
  10. sqlite管理工具
  11. 怎么把video文件改成mp4_GiliSoft Video Converter将MP4视频转换成M4V格式教程
  12. java基础学习之对象转型
  13. hashmap什么时候由链表转为红黑树
  14. 安卓上哔哩哔哩视频的导出
  15. wifi万能钥匙破解隔壁无线网以及查看破解密码
  16. 增高助长~~~~~~~~~~~~
  17. 转换罗马数字,输入一串数字字符串,将其转化为希腊字符串。
  18. 【项目】区块链+人工智能 ---PAI白皮书分析(二)
  19. 知识图谱入门 (一) 知识图谱与语义技术概览
  20. ACM准备之路(蓝桥杯8)数字图形

热门文章

  1. 第2章 蓝牙降噪耳机测试维度
  2. 《Activiti工作流框架》专题(一)-Activiti工作流框架基础入门
  3. C#基础知识梳理系列十五:反射
  4. JSP——连接数据库、编写api接口
  5. Python基础之函数,面向对象
  6. Java-String的用法
  7. SpringBoot系列之切换log4j日志框架
  8. Twincat 3 初识
  9. MySQL日志(一)—— 慢查询日志slow log
  10. 第十三周总结——认清自己