pm_suspend代码分析
v0.01 20190902 Init
v0.02 20191011 优化章节,优化部分描述。
1 概念
System Sleep States是整个系统全局的低功耗模式,用户空间代码无法执行,系统整体活动显著减少。
2 支持哪些Sleep States
总共支持4中睡眠状态,按睡眠深度由低到高依次是: freeze,standby,mem 和 disk。
可以通过接口 /sys/power/state 查询和进入。如果某状态查不到,则说明不支持,freeze和mem是永远支持的。
mem和disk状态做了细分, 通过以下方式查询和配置。
[root@localhost power]# cat /sys/power/disk
[shutdown] reboot suspend test_resume
[root@localhost power]# cat /sys/power/mem_sleep
s2idle [deep]
3 代码分布
系统睡眠相关的主要代码在kernel/power目录下,包含sysfs接口实现,模式定义。当然被调用的代码不在这里,比如dpm,及syscore相关的代码,会放在drivers/base/power/main.c, drivers/base/syscore.c等处。
main.c: pm core初始化,主要sysfs接口的实现,调用各状态的入口函数。
suspend.c: 实现freeze,standby和mem三个状态,入口函数是pm_suspend
(),重要配置函数suspend_set_ops
()。
hibernate.c: 实现disk状态,入口函数hibernate()。
四种状态定义如下:
# include/linux/suspend.h
36 #define PM_SUSPEND_ON ((__force suspend_state_t) 0)
37 #define PM_SUSPEND_TO_IDLE ((__force suspend_state_t) 1)
38 #define PM_SUSPEND_STANDBY ((__force suspend_state_t) 2)
39 #define PM_SUSPEND_MEM ((__force suspend_state_t) 3)
40 #define PM_SUSPEND_MIN PM_SUSPEND_TO_IDLE
41 #define PM_SUSPEND_MAX ((__force suspend_state_t) 4)
#对应关系如下:
freeze: PM_SUSPEND_TO_IDLE
standby: PM_SUSPEND_STANDBY
mem: PM_SUSPEND_MEM
disk: PM_SUSPEND_MAX
4 重点流程讲解
4.1 pm_suspend()
pm_suspend(kernel/power/suspend.c)
enter_state()
suspend_prepare() //console、通知链、并suspend所有进程线程
suspend_devices_and_enter()
platform_suspend_begin()
dpm_suspend_start() //调用dpm_prepare和dpm_suspend, 即所有devices做suspend
suspend_enter() //suspend_late, suspend_noirq,关从核,关中断,syscore_suspend
suspend_ops->enter()
说明一下,syscore_suspend存在的原因是,有些子系统执行suspend/resume/shutdown操作,要求只有一个CPU在线,且要关闭中断。比如acpi, clk,cpufreq,gpio,iommu,irqchip,irq,time,所以增加了syscore,等suspend的最后阶段调用。
这部分代码在drivers/base/syscore.c实现的。