Linux睡眠唤醒调试方法
Linux中的挂起、休眠,一般是指以下四种状态:
- STI(suspend to idle):是一种通用的、纯软件、轻量级系统睡眠状态
- Standby(power-on suspend):是一种适度的功耗节省状态,同时系统也可以比较快的唤醒
- STR(suspend to ram):提供了比较显著的功耗节省,系统中除了内存之外的部件都进入了低功耗状态
- STD(suspend to disk):提供最大程度的功耗节省
State | ACPI state | Label |
---|---|---|
STI | S0 | s2idle/freeze |
standby | S1 | shallow/standby |
STR | S3 | deep |
STD | S4 | disk |
具体的状态描述可以参考内核文档Documentation/power/states.txt
基础调试方法
关闭串口睡眠:在启动参数中增加
no_console_suspend ignore_loglevel
,S3调试日志如下1
2
3
4
5
6
7
8
9
10
11
12
13
14
15root@Ubuntu:~# echo mem > /sys/power/state
[ 74.403728] PM: suspend entry (deep)
[ 74.411597] Filesystems sync: 0.004 seconds
[ 74.576746] Freezing user space processes ... (elapsed 0.003 seconds) done.
[ 74.586948] OOM killer disabled.
[ 74.590196] Freezing remaining freezable tasks ... (elapsed 0.001 seconds) done.
[ 74.604967] pcieport 0000:00:04.0: pciehp: Timeout on hotplug command 0x1438 (issued 71912 msec ago)
[ 74.605025] pcieport 0000:00:05.0: pciehp: Timeout on hotplug command 0x1438 (issued 71884 msec ago)
[ 74.617628] macb 3200c000.ethernet eth0: Link is Down
[ 74.629279] macb 3200c000.ethernet: gem-ptp-timer ptp clock unregistered.
[ 74.752892] pcieport 0000:00:01.0: pciehp: Timeout on hotplug command 0x1438 (issued 72084 msec ago)
[ 76.636865] pcieport 0000:00:04.0: pciehp: Timeout on hotplug command 0x0418 (issued 2020 msec ago)
[ 76.644855] pcieport 0000:00:05.0: pciehp: Timeout on hotplug command 0x0418 (issued 2024 msec ago)
[ 76.784854] pcieport 0000:00:01.0: pciehp: Timeout on hotplug command 0x0418 (issued 2024 msec ago)
[ 76.917236] Disabling non-boot CPUs ...在启动参数中加入
initcall_debug
,打印init函数的进入和返回log,可以定位哪个init函数运行失败或运行时间过长,S3调试日志如下1
2
3
4
5
6
7
8
9
10
11
12
13
14root@Ubuntu:~# echo mem > /sys/power/state
[ 409.072355] PM: suspend entry (deep)
[ 409.087412] Filesystems sync: 0.011 seconds
[ 409.260860] Freezing user space processes ... (elapsed 0.003 seconds) done.
[ 409.271298] OOM killer disabled.
[ 409.274561] Freezing remaining freezable tasks ... (elapsed 0.001 seconds) done.
[ 409.284345] rtc rtc0: calling rtc_suspend+0x0/0x138 @ 840, parent: 0-0068
[ 409.291569] rtc rtc0: rtc_suspend+0x0/0x138 returned 0 after 317 usecs
[ 409.298209] mtd mtd1ro: calling mtd_cls_suspend+0x0/0x78 @ 840, parent: 10000000.lbc_nor
[ 409.306323] mtd mtd1ro: mtd_cls_suspend+0x0/0x78 returned 0 after 1 usecs
[ 409.313140] mtd mtd1: calling mtd_cls_suspend+0x0/0x78 @ 840, parent: 10000000.lbc_nor
[ 409.321075] mtd mtd1: mtd_cls_suspend+0x0/0x78 returned 0 after 1 usecs
...
[ 412.886230] Disabling non-boot CPUs ...禁用异步suspend resume设备,排除设备驱动的pm问题
echo 0 > /sys/power/pm_async
,在Linux异步对设备进行suspend resume时出现问题的情况下,可以禁用异步suspend resume来排查设备驱动pm问题
PM_DEBUG选项调试休眠唤醒
打开CONFIG_PM_DEBUG选项,使用/sys/power/pm_test
来测试休眠、唤醒,pm_test里面一共有5种测试模式
- freezer:测试进程冻结
- devices:测试进程冻结和设备驱动suspend和resume
- platform:测试进程冻结、设备驱动suspend和resume、suspending platform global control methods
- processors:测试进程冻结、设备驱动suspend resume、suspending platform global control methods、关闭nonboot CPU
- core:测试进程冻结、设备驱动suspend resume、关闭nonboot CPU、suspending platform/system devices
使用该方法进行调试时,需要往/sys/power/pm_test
中写入对应的测试模式,然后进行S3 S4休眠操作,休眠流程走完后,5秒后会自动唤醒系统,测试的时候可以从freezer devices platform…逐步进行测试
详细描述可参考内核文档basic-pm-debugging.txt
freezer休眠唤醒调试日志
1 | root@Ubuntu:/sys/power# cat /proc/cmdline |
devices休眠唤醒调试日志
1 | root@Ubuntu:/sys/power# cat /proc/cmdline |
总结
- 调试休眠和唤醒首先配置启动参数
no_console_suspend initcall_debug ignore_loglevel
,通过打印的日志信息基本上可以排查出问题原因 - 通过上面步骤无法排查出阻碍休眠的原因时,可以打开
CONFIG_PM_DEBUG
选项,往/sys/power/pm_test
中写入freezer devices platform…逐步进行测试,观察哪个测试无法通过,可以对应查找问题