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實現的。