Skip to main content
 首页 » 操作系统

Linux5.2/Documentation/power/basic-pm-debugging.txt 翻译 —— 调试休眠和挂起

2022年07月19日24zhwl

调试休眠和挂起


(C) 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

这是默认和推荐的休眠模式。

不幸的是,休眠的“platform”模式在某些BIOS损坏的系统上不起作用。 在这种情况下,休眠的“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 
 - 测试进程冻结,设备挂起和平台全局控制方法(*) 
 
processors 
 - 测试进程冻结,设备挂起,平台全局控制方法(*)以及禁用非引导CPU 
 
core 
 - 测试进程冻结,设备挂起,平台全局控制方法(*),禁用非引导CPU和挂起平台/系统设备 
 
(*)平台全局控制方法仅适用于ACPI系统,仅在休眠模式设置为“platform”时进行测试

要使用其中一个,必须将相应的字符串写入 /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”测试失败,则很可能存在无法挂起或恢复其设备的驱动程序(在后一种情况下,系统可能会在测试后hang(挂起)或变得不稳定,因此请考虑到这一点)。 要查找此驱动程序,您可以根据规则执行二分搜索:
    - 如果测试失败,卸载当前加载的一半驱动程序并重复测试(这可能涉及重新启动系统,因此请始终记下测试前已加载的驱动程序),
    - 如果测试成功,请加载最近卸载的一半驱动程序并重复。

  一旦找到了故障的驱动程序(可能不仅仅只有一个),您每次在休眠之前都必须卸载它。 在这种情况下,请务必报告驱动程序的问题。

  卸载所有模块后,“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”测试失败都可能导致系统挂起(hang)或变得不稳定,请注意。 这种故障通常表明一个严重的问题很可能与硬件有关,但无论如何请报告。

b)测试最小配置

  如果所有休眠测试模式都有效(都是ok的),则可以使用 "init=/bin/bash" 命令行参数启动系统,并尝试在“rebo​​ot”,“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上,还可以使用Documentation/power/s2ram.txt中记录的PM_TRACE机制。

2.测试暂停到RAM(STR)

  为了验证STR的工作原理,使用http://suspend.sf.net上提供的s2ram工具并记录在 http://en.opensuse.org/SDB:Suspend_to_RAM(S2RAM_LINK)。即,在将“freezer”,“devices”,“platform”,“processor”或“core”写入/sys/power/pm_test(如果内核使用了CONFIG_PM_DEBUG 编译选项)之后,挂起代码将在给定字符串的测试模式中起作用。 STR测试模式的定义方式与休眠方式相同,因此有关它们的更多信息,请参阅第1节。 特别是,“core”测试允许您测试除平台固件的实际调用之外的所有内容,以使系统进入睡眠状态。

  除此之外,在/sys/power/pm_test 的帮助下进行测试可以让您识别无法挂起或恢复其设备的驱动程序。 在STR转换之前,每次都应该卸载它们。接下来,您可以按照S2RAM_LINK上的说明测试系统,但如果它不能“开箱即用”("out of the box"),您可能需要使用“init=/bin/bash”启动它并在最小配置中测试s2ram。 在这种情况下,您可以按照与第1节中描述的类似的过程搜索失败的驱动程序。如果发现某些失败的驱动程序,则必须在每次STR转换之前卸载它们(即在您之前) 运行s2ram),请报告问题。

有一个debugfs条目,显示suspend到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个失败的设备,错误码和suspend失败的步骤。


本文参考链接:https://www.cnblogs.com/hellokitty2/p/11073937.html