一、Opportunistic sleep引言
1. 背景
(1) android 面临的问题
Opportunistic sleep: 当没有任务时,需要寻找时机,进入suspended
(2) 3类同步问题
a. 内核:driver处理event的过程中,系统不能suspend
b. 用户:用户进程处理的过程中系统不能suspend
c. 内核与用户交互:
休眠过程中,触发event, 需abort suspend流程;
event 事件需用户态处理完毕后,才能suspend;
2. earlysuspend
3. autosleep
4. wakeup_count
5. 三种休眠机制的比较
(1)有关earlysuspend的讨论
a. 更改了suspend 流程,引入了earlysuspend 接口;
b. 社区对该patch,有误解,认为其要替代runtime;
c. wakelock 实现过于复杂,名称易造成误解;
d. mini-summit: 有nokia 开发者,缺乏android 开发者,引入了非技术性的讨论;
e. 应该使用pm_runtime, cpuidle; susupend 不应该存在;
f. 唤醒源的处理过程,贯穿整个系统,影响较大;
(2)有关autosleep的讨论
a. android 市场份额越来越大,很多driver src code 脱离了mainline;
b. Linus 认为需要合并android 的特性:suspend block;
c. Rafael J. Wysocki 认为时机已经成熟,提出了新的解决方案;
d. 社区对该opportunisic suspend patch, 有误解,引入了非技术性的讨论:重新设计后,命名为autosleep;
e. 考虑到android 的兼容性,接口上保留了wakelock; 实现上,进行了改进;
(3)有关wakeup_count的讨论
a. 在userspace 基于wakeup_count 实现的 opportunistic sleep 机制;(与autosleep 类似);
b. 内核空间,无wake_lock 概念;
c. 无suspend block 概念;
d. suspend 触发的时机,全部交由用户空间负责;
6. 引入autosleep | wakeup count的理由
(1)earlysuspend 被内核抛弃,需自己打补丁;
(2)使用earlysuspend, 对内核改动较大,更改了suspend 流程, 无法合并入mainline;
(3)对设备驱动影响较大,需额外实现earlysuspend 接口,不利于upstream;
(4)earlysuspend 已存在的问题:例如只支持开关屏时执行earlysuspend, 不利于动态功耗的优化;
(5)pm_runtime 已经在display, usb 等设备使用;
(6)upstream 的需求;
二、opportunistic sleep 框架
三、wakeup source 框架
1. 功能
a. 抽象wakeup source和wakeup event的概念;
b. 向各个device driver提供wakeup source的注册、使能等接口;
c. 向各个device driver提供wakeup event的上报、停止等接口;
d. 向上层的PM core(包括wakeup count、auto sleep、suspend、hibernate等模块)提供wakeup event的查询接
口,以判断是否可以suspend、是否需要终止正在进行的suspend;
2. 数据结构
(1)registered wakeup events(cnt)和saved_count;
(2)wakeup events in progress(inpr);
3. 相关接口
四、wakeup count框架
1. 目标
有唤醒事件需处理时:
若系统在运行过程中,不能进入suspend;
若已进入suspend 流程,需及时退出;
2. 接口
a. bool pm_get_wakeup_count(unsigned int *count, bool block);
b. bool pm_save_wakeup_count(unsigned int count);
3. 流程