英文

hwpoison

什麼是 hwpoison?

即將推出的 Intel CPU 支援從一些記憶體錯誤中恢復 (MCA recovery)。 這要求作業系統宣告一個頁面為“已中毒”,殺死與其關聯的程序,並避免將來使用它。

此補丁集在 VM 中實現了必要的基礎架構。

引用概述註釋

High level machine check handler. Handles pages reported by the
hardware as being corrupted usually due to a 2bit ECC memory or cache
failure.

This focusses on pages detected as corrupted in the background.
When the current CPU tries to consume corruption the currently
running process can just be killed directly instead. This implies
that if the error cannot be handled for some reason it's safe to
just ignore it because no corruption has been consumed yet. Instead
when that happens another machine check will happen.

Handles page cache pages in various states. The tricky part
here is that we can access any page asynchronous to other VM
users, because memory failures could happen anytime and anywhere,
possibly violating some of their assumptions. This is why this code
has to be extremely careful. Generally it tries to use normal locking
rules, as in get the standard locks, even if that means the
error handling takes potentially a long time.

Some of the operations here are somewhat inefficient and have non
linear algorithmic complexity, because the data structures have not
been optimized for this case. This is in particular the case
for the mapping from a vma to a process. Since this case is expected
to be rare we hope we can get away with this.

該程式碼由 mm/memory-failure.c 中的高階處理程式、新的頁面中毒位以及 VM 中用於處理中毒頁面的各種檢查組成。

目前的主要目標是 KVM 客戶機,但它適用於所有型別的應用程式。 KVM 支援需要最新的 qemu-kvm 版本。

對於 KVM 用途,需要一種新的訊號型別,以便 KVM 可以使用正確的地址將機器檢查注入到客戶機中。 從理論上講,這也允許其他應用程式處理記憶體故障。 預計大多數應用程式不會這樣做,但一些非常專業的應用程式可能會這樣做。

故障恢復模式

記憶體故障恢復有兩種(實際上是三種)模式

vm.memory_failure_recovery sysctl 設定為零

所有記憶體故障都會導致 panic。 不要嘗試恢復。

提前殺死

(可以全域性和按程序控制)一旦檢測到錯誤,就嚮應用程式傳送 SIGBUS。 這允許能夠以溫和的方式處理記憶體錯誤的應用程式(例如,刪除受影響的物件)。 這是 KVM qemu 使用的模式。

延遲殺死

當應用程式遇到損壞的頁面時傳送 SIGBUS。 這最適合未感知記憶體錯誤的應用程式和預設值。 請注意,某些頁面始終作為延遲殺死處理。

使用者控制

vm.memory_failure_recovery

請參閱 sysctl.txt

vm.memory_failure_early_kill

全域性啟用提前殺死模式

PR_MCE_KILL

設定提前/延遲殺死模式/恢復為系統預設值

arg1: PR_MCE_KILL_CLEAR

恢復為系統預設值

arg1: PR_MCE_KILL_SET

arg2 定義執行緒特定模式

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 的 hwpoison-inject 模組 /sys/kernel/debug/hwpoison/

    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 測試程式,請參見下文。

參考

http://halobates.de/mce-lc09-2.pdf

LinuxCon 09 的概述演示

git://git.kernel.org/pub/scm/utils/cpu/mce/mce-test.git

測試套件(tsrc 中特定於 hwpoison 的可移植測試)

git://git.kernel.org/pub/scm/utils/cpu/mce/mce-inject.git

x86 特定注入器

限制

  • 並非所有頁面型別都受支援,並且永遠不會受支援。 大多數核心內部物件無法恢復,目前只能恢復 LRU 頁面。

--- Andi Kleen, 2009 年 10 月