hwpoison 【ChatGPT】

发布时间 2023-12-12 23:08:01作者: 摩斯电码

"hwpoison"是什么?

即将推出的英特尔CPU支持从一些内存错误(MCA恢复)中恢复。这需要操作系统声明一个页面为“毒害”,终止与之关联的进程,并避免将来使用它。

这个补丁包在虚拟机中实现了必要的基础设施。

引用概述评论:

高级机器检查处理程序。处理硬件报告的页面通常由于2位ECC内存或缓存故障而被损坏。

这专注于在后台检测到损坏的页面。当当前CPU尝试消耗损坏时,当前运行的进程可以直接被终止。这意味着,如果由于某种原因无法处理错误,那么安全地忽略它是可以的,因为尚未发生任何损坏。相反,当发生这种情况时,将会发生另一个机器检查。

处理各种状态的页面缓存页面。这里的棘手之处在于我们可以异步访问任何页面,因为内存故障可能随时发生,可能违反一些假设。这就是为什么这段代码必须非常小心谨慎。通常情况下,它试图使用正常的锁定规则,即获取标准锁定,即使这可能意味着错误处理需要很长时间。

这里的一些操作有些低效,并且具有非线性的算法复杂性,因为数据结构并未针对这种情况进行优化。这特别适用于从VMA到进程的映射。由于这种情况预计是罕见的,我们希望可以摆脱这一点。

代码包括mm/memory-failure.c中的高级处理程序、新的页面毒害位以及虚拟机中处理毒害页面的各种检查。

目前的主要目标是KVM客户端,但适用于各种应用程序。KVM支持需要最新的qemu-kvm版本。

对于KVM的使用,需要一种新的信号类型,以便KVM可以将机器检查注入到具有适当地址的客户端。理论上,这也允许其他应用程序处理内存故障。预期大多数应用程序不会这样做,但一些非常专业的应用程序可能会。

故障恢复模式

内存故障恢复有两种(实际上是三种)模式:

  1. vm.memory_failure_recovery设置为零:

    所有内存故障都会导致系统崩溃,不会尝试恢复。

  2. 早期终止(可以全局和每个进程单独控制):

    一旦检测到错误,立即向应用程序发送SIGBUS信号。这允许能够以温和方式处理内存错误的应用程序(例如,丢弃受影响的对象)。这是KVM qemu使用的模式。

  3. 晚期终止:

    当应用程序访问到损坏的页面时发送SIGBUS。这适用于不了解内存错误的应用程序,并且是默认模式。需要注意的是,某些页面始终被视为晚期终止。

用户可以通过以下方式控制和配置:

  • vm.memory_failure_recovery:参见sysctl.txt。

  • vm.memory_failure_early_kill:全局启用早期终止模式。

  • PR_MCE_KILL:设置早期/晚期终止模式或恢复为系统默认模式。

    • arg1: PR_MCE_KILL_CLEAR:恢复为系统默认模式。
    • arg1: PR_MCE_KILL_SETarg2定义线程特定模式。
      • PR_MCE_KILL_EARLY:早期终止。
      • PR_MCE_KILL_LATE:晚期终止。
      • PR_MCE_KILL_DEFAULT:使用系统全局默认模式。
        需要注意的是,如果您想要有一个专用的线程代表进程处理SIGBUS(BUS_MCEERR_AO),您应该在指定的线程上调用prctl(PR_MCE_KILL_EARLY)。否则,SIGBUS将发送到主线程。
  • PR_MCE_KILL_GET:返回当前模式。

测试

  • 使用madvise(MADV_HWPOISON, ....)(作为root用户)- 为了测试,在进程中毒害一个页面
  • 通过debugfs /sys/kernel/debug/hwpoison/中的hwpoison-inject模块
    • corrupt-pfn
      • 在此文件中注入PFN指定的hwpoison故障。这会进行一些早期过滤,以避免在测试套件中出现意外损坏的页面。
    • unpoison-pfn
      • 在此文件中软件解毒指定的PFN页面。这样页面可以再次被重用。这仅适用于Linux注入的故障,而不适用于真实的内存故障。一旦发生任何硬件内存故障,此功能将被禁用。
        请注意,这些注入接口不稳定,可能会在内核版本之间发生变化。
  • corrupt-filter-dev-major, corrupt-filter-dev-minor
    • 仅处理与由块设备主/次定义的文件系统相关联的页面的内存故障。-1U是通配符值。这应该仅用于使用人工注入进行测试。
  • corrupt-filter-memcg
    • 将注入限制为由memgroup拥有的页面。由memcg的inode号指定。
    • 示例:
      mkdir /sys/fs/cgroup/mem/hwpoison
      
      usemem -m 100 -s 1000 &
      echo `jobs -p` > /sys/fs/cgroup/mem/hwpoison/tasks
      
      memcg_ino=$(ls -id /sys/fs/cgroup/mem/hwpoison | cut -f1 -d' ')
      echo $memcg_ino > /debug/hwpoison/corrupt-filter-memcg
      
      page-types -p `pidof init`   --hwpoison  # shall do nothing
      page-types -p `pidof usemem` --hwpoison  # poison its pages
      
  • corrupt-filter-flags-mask, corrupt-filter-flags-value
    • 当指定时,仅在((page_flags & mask) == value)时毒害页面。这允许对许多类型的页面进行压力测试。page_flags与/proc/kpageflags中的相同。标志位在include/linux/kernel-page-flags.h中定义,并在《检查进程页表》中有文档记录。
  • 架构特定的MCE注入器
    • x86具有mce-inject、mce-test
    • mce-test中有一些可移植的hwpoison测试程序,见下文。

参考资料

限制

并非所有页面类型都受支持,而且永远也不会受支持。目前只能恢复大多数内核内部对象,仅支持LRU页面。

--- Andi Kleen,2009年10月