除錯休眠和掛起¶
2007 Rafael J. Wysocki <rjw@sisk.pl>, GPL
1. 測試休眠(也稱為掛起到硬碟或 STD)¶
要檢查休眠是否工作,您可以嘗試在“reboot”模式下休眠
# echo reboot > /sys/power/disk
# echo disk > /sys/power/state
系統應該建立一個休眠映象,重新啟動,恢復並返回到您開始轉換的命令提示符處。如果發生這種情況,休眠很可能工作正常。儘管如此,您仍然需要連續重複測試幾次以獲得信心。[這是必要的,因為某些問題僅在第二次嘗試掛起和恢復系統時才會出現。]此外,在“reboot”和“shutdown”模式下休眠會導致 PM 核心跳過某些與平臺相關的回撥,而在 ACPI 系統上,這些回撥可能對於使休眠工作是必要的。因此,如果您的機器無法在“reboot”模式下休眠或恢復,您應該嘗試“platform”模式
# echo platform > /sys/power/disk
# echo disk > /sys/power/state
這是預設和推薦的休眠模式。
不幸的是,在某些具有損壞 BIOS 的系統上,“platform”休眠模式不起作用。在這種情況下,“shutdown”休眠模式可能會起作用
# echo shutdown > /sys/power/disk
# echo disk > /sys/power/state
(它類似於“reboot”模式,但需要您按電源按鈕才能使系統恢復)。
如果“platform”和“shutdown”休眠模式都不起作用,您將需要確定哪裡出了問題。
a) 測試休眠模式¶
要找出為什麼休眠在您的系統上失敗,您可以使用一個特殊的測試工具,如果核心編譯時設定了 CONFIG_PM_DEBUG。然後,可以使用檔案 /sys/power/pm_test 使休眠核心在測試模式下執行。有 5 種測試模式可用
- freezer
測試程序的凍結
- devices
測試程序的凍結和裝置的掛起
- platform
測試程序的凍結、裝置的掛起和平臺全域性控制方法 [1]
- processors
測試程序的凍結、裝置的掛起、平臺全域性控制方法 [1] 和非啟動 CPU 的停用
- core
測試程序的凍結、裝置的掛起、平臺全域性控制方法[1]、非啟動 CPU 的停用和平臺/系統裝置的掛起
要使用其中一種方法,需要將相應的字串寫入 /sys/power/pm_test(例如,“devices”來測試程序的凍結和裝置的掛起)併發出標準休眠命令。例如,要將“devices”測試模式與“platform”休眠模式一起使用,您應該執行以下操作
# echo devices > /sys/power/pm_test
# echo platform > /sys/power/disk
# echo disk > /sys/power/state
然後,核心將嘗試凍結程序,掛起裝置,等待幾秒鐘(預設為 5 秒,但可以透過 suspend.pm_test_delay 模組引數配置),恢復裝置並解凍程序。如果將“platform”寫入 /sys/power/pm_test,則在掛起裝置後,核心還將呼叫用於準備平臺韌體以進行休眠的全域性控制方法(例如,ACPI 全域性控制方法)。接下來,它將等待可配置的秒數並呼叫用於取消休眠的平臺(例如,ACPI)全域性方法等。
將“none”寫入 /sys/power/pm_test 會導致核心切換到正常的休眠/掛起操作。此外,當開啟以進行讀取時,/sys/power/pm_test 包含一個以空格分隔的所有可用測試列表(包括代表正常功能的“none”),其中當前測試級別由方括號指示。
一般來說,正如您所看到的,每個測試級別都比前一個級別更具“侵入性”,並且“core”級別在不建立休眠映象的情況下儘可能深入地測試硬體和驅動程式。顯然,如果“devices”測試失敗,“platform”測試也會失敗,依此類推。因此,作為經驗法則,您應該從“freezer”開始嘗試測試模式,依次透過“devices”、“platform”和“processors”直到“core”(在每個級別重複測試幾次,以確保避免任何隨機因素)。
如果“freezer”測試失敗,則存在無法凍結的任務(在這種情況下,通常可以透過分析失敗測試後獲得的 dmesg 輸出來識別有問題的任務)。在此級別上的失敗通常意味著任務凍結子系統存在問題,應予以報告。
如果“devices”測試失敗,則很可能有一個驅動程式無法掛起或恢復其裝置(在後一種情況下,系統可能會在測試後掛起或變得不穩定,因此請考慮到這一點)。要找到此驅動程式,您可以根據以下規則進行二分查詢
如果測試失敗,解除安裝當前載入的驅動程式的一半並重復(這可能涉及重新啟動系統,因此請始終注意在測試之前已載入哪些驅動程式),
如果測試成功,載入您最近解除安裝的驅動程式的一半並重復。
一旦您找到失敗的驅動程式(可能不止一個),您必須在每次休眠之前解除安裝它。在這種情況下,請務必報告驅動程式的問題。
也可能在您解除安裝所有模組後,“devices”測試仍然失敗。在這種情況下,您可能希望在核心配置中查詢可以編譯為模組的驅動程式(並使用編譯為模組的這些驅動程式再次進行測試)。您也可以嘗試使用一些特殊的核心命令列選項,例如“noapic”、“noacpi”甚至“acpi=off”。
如果“platform”測試失敗,則說明您的系統上平臺(例如,ACPI)韌體的處理存在問題。在這種情況下,“platform”休眠模式不太可能工作。您可以嘗試“shutdown”模式,但這只是一種權宜之計。
如果“processors”測試失敗,則非啟動 CPU 的停用/啟用不起作用(當然,這可能只是 SMP 系統上的問題),應報告該問題。在這種情況下,您也可以嘗試使用 /sys/devices/system/cpu/cpu*/online sysfs 屬性來關閉和開啟非啟動 CPU,看看是否有效。
如果“core”測試失敗,這意味著系統/平臺裝置的掛起失敗(這些裝置在中斷關閉的情況下在一個 CPU 上掛起),那麼問題很可能與硬體相關且很嚴重,因此應報告該問題。
任何“platform”、“processors”或“core”測試的失敗都可能導致您的系統掛起或變得不穩定,因此請注意。這種失敗通常表明一個嚴重的問題,很可能與硬體有關,但請無論如何報告它。
b) 測試最小配置¶
如果所有休眠測試模式都有效,您可以使用“init=/bin/bash”命令列引數啟動系統,並嘗試在“reboot”、“shutdown”和“platform”模式下休眠。如果這不起作用,則可能存在一個靜態編譯到核心中的驅動程式存在問題,您可以嘗試將更多驅動程式編譯為模組,以便可以單獨進行測試。否則,模組化驅動程式存在問題,您可以透過載入通常使用的一半模組並按照以下演算法進行二分查詢來找到它:- 如果載入了 n 個模組並且嘗試掛起和恢復失敗,則解除安裝 n/2 個模組並重試(這可能涉及重新啟動系統),- 如果載入了 n 個模組並且嘗試掛起和恢復成功,則載入 n/2 個模組並重試。
同樣,如果您找到有問題的模組,則必須在每次休眠之前解除安裝它,並請報告它的問題。
c) 使用“test_resume”休眠選項¶
/sys/power/disk 通常告訴核心在建立休眠映象後該怎麼做。可用選項之一是“test_resume”,它會導致剛剛建立的映象用於立即恢復。也就是說,在執行
# echo test_resume > /sys/power/disk
# echo disk > /sys/power/state
將建立一個休眠映象,並且將立即觸發從該映象的恢復,而無需以任何方式涉及平臺韌體。
該測試可用於檢查從休眠狀態恢復的失敗是否與與平臺韌體的錯誤互動有關。也就是說,如果上述方法每次都有效,但從實際休眠狀態恢復不起作用或不可靠,則平臺韌體可能對失敗負責。
在支援使用不同核心來恢復休眠映象的架構和平臺上(即,用於從儲存讀取映象並將其載入到記憶體中的核心與映象中包含的核心不同)或支援核心地址空間隨機化,它也可用於檢查恢復失敗是否可能與恢復核心和映象核心之間的差異有關。
d) 高階除錯¶
如果即使在最小配置下休眠在您的系統上也不起作用,並且將更多驅動程式編譯為模組不切實際或某些模組無法解除安裝,您可以使用更高階的除錯技術之一來查詢問題。首先,如果您的機器中有一個序列埠,您可以使用“no_console_suspend”引數啟動核心,並嘗試使用序列控制檯記錄核心訊息。這可能會為您提供有關掛起(恢復)失敗原因的一些資訊。或者,可以使用 FireWire 埠透過 firescope 進行除錯 (http://v3.sk/~lkundrak/firescope/)。在 x86 上,也可以使用 如何讓 s2ram 工作 中記錄的 PM_TRACE 機制。
2. 測試掛起到 RAM (STR)¶
要驗證 STR 是否有效,通常更方便使用 http://suspend.sf.net 提供的 s2ram 工具,並在 http://en.opensuse.org/SDB:Suspend_to_RAM (S2RAM_LINK) 中記錄。
也就是說,在將“freezer”、“devices”、“platform”、“processors”或“core”寫入 /sys/power/pm_test(如果核心編譯時設定了 CONFIG_PM_DEBUG,則可用)後,掛起程式碼將以與給定字串對應的測試模式工作。STR 測試模式的定義方式與休眠相同,因此請參閱第 1 節以獲取有關它們的更多資訊。特別是,“core”測試允許您測試除實際呼叫平臺韌體以使系統進入睡眠狀態之外的所有內容。
其中,藉助 /sys/power/pm_test 進行測試可以讓您識別出無法掛起或恢復其裝置的驅動程式。每次 STR 轉換之前都應解除安裝它們。
接下來,您可以按照 S2RAM_LINK 中的說明測試系統,但如果它不能“開箱即用”,您可能需要使用“init=/bin/bash”啟動它,並在最小配置中測試 s2ram。在這種情況下,您可以透過遵循與第 1 節中描述的過程類似的過程來搜尋失敗的驅動程式。如果您找到一些失敗的驅動程式,您將必須在每次 STR 轉換之前(即,在您執行 s2ram 之前)解除安裝它們,並請報告它們的問題。
有一個 debugfs 條目顯示掛起到 RAM 的統計資訊。這是一個輸出示例
# mount -t debugfs none /sys/kernel/debug
# cat /sys/kernel/debug/suspend_stats
success: 20
fail: 5
failed_freeze: 0
failed_prepare: 0
failed_suspend: 5
failed_suspend_noirq: 0
failed_resume: 0
failed_resume_noirq: 0
failures:
last_failed_dev: alarm
adc
last_failed_errno: -16
-16
last_failed_step: suspend
suspend
欄位 success 表示掛起到 RAM 的成功次數,欄位 fail 表示失敗次數。其他的是掛起到 RAM 的不同步驟的失敗次數。suspend_stats 僅列出最後 2 個失敗的裝置,錯誤號和掛起的失敗步驟。