Linux下PowerManagement开发总结
本⽂作为⼀个提纲挈领的介绍性⽂档,后⾯会以此展开,逐渐丰富。
1. 前⾔
在《》中介绍了PM开发的⼀般流程,重点是好的模型、简单有效的接⼝参数、可量化的测试环境以及可独性强的输出。
内核中功耗开发⽆论是新模型开发还是已有模型的调优,都需要了解现有的框架,遵循已有框架,简单有效的修改。这就需要了解《》,关于Linux省电,从开机-->运⾏-->suspend-->关机这四种状态,开机/关机不太受关注,但是⾜够快也是省电的⼀种。
在进⼊细节之前,了解⼀下Linux中PM框架()有助于下⾯学习。
suspend()是⼀种深层次的省电,运⾏态情况下省电就⼋仙过海各显神通了。如果将电流曲线以timeline形式画出,功耗就是曲线覆盖的阴影⾯积了。⼀个任务来看,⾯积越⼩越好,当然时间也要满⾜需求。
suspend是系统级省电,涉及到各外设、Memory、CPU等等各种设备,总之是尽量关闭。只保留不能断电部分⽤于唤醒系统,以及系统恢复,⽐如外设唤醒中断、RAM Retention等。suspend本⾝也有不同种
类,mem/standby/hibernation。⼤部分使⽤的还是mem,即suspend to ram。此时内核处于冻结状态(),系统tick停⽌,只有中断将其从睡眠唤醒才会去处理任务。
在系统运⾏过程中省电,则要复杂多变多了。对于CPU在⼯作是根据负载动态调频调压(),没有⼯作处理的时候进⼊IDLE(),更进⼀步在多核情况下CPU都可以被热插拔();对于各种其他外设可以根据是否被使⽤⽽动态关闭()。当然这些调节都要保证性能的输出()。
在系统运⾏过程中,⾼温可能导致设别损坏,因此根据温度来分配功耗也是⼀门必要⼿段()。
当然省电也离不开⼀些基础功能⽐如时钟控制()、供电开关()、电源域划分(),以及内核和应⽤都会⽤到的睡眠锁、唤醒源、唤醒事件都可以归到唤醒事件框架中()。
系统的供电是使⽤AC还是电池,备抽象成。
⼯欲善其事,必先利其器。没有⼀个好的⼯具环境,去量化,只会⼀抹⿊,如何验证模型正确与否?如何确定参数是否调优?《》中介绍了ARM开源的两款⼯具和,以及⼀些⾃⼰开发的⼯具集。
在了解开发对象和有了⼯具之后,当然要去试⼀试了。《》中详细记录的⼯具的使⽤、优化流程和结果。
在⽂章的结尾,对⼀些其相关点进⾏了罗列与总结《》。
2. 开发流程
针对⼀个PM feature进⾏开发,设计模型是第⼀步。模型设计好之后,还要保留参数接⼝,可以基于这些参数针对特殊个体进⾏优化。
建⽴⼀个可以快速迭代、准确可靠、可量化的验证环境尤其重要。⼀⽅⾯可以验证设计的模型是否有效、正确;另⼀⽅⾯还可以调整到最适合的参数。
针对嵌⼊式设备来说,最主要的是达到性能和功耗的平衡:在满⾜性能要求的前提下,尽量降低功耗。
这就涉及到如何去量化性能(Performance)和功耗(Power)。
量化功耗⽐较简单,可以通过Power Monitor在测量点获得数据(测量点的确定很重要!);量化性能就⽐较复杂了,针对不同的功能模块,需要不同的性能分析⼯具。
另外,针对不同的模块,可能需要产⽣特定的workload。
最后,可读性强的统计信息或者可视化图表也更有利于得出分析结果。
以LISA为例,可以使⽤workload rt-app产⽣特定调度侧率,运⾏时间,运⾏在特定CPU上的线程,保证运⾏环境⼀致。
通过devlib可以获得测试过程中的Power Monitor数据。
然后通过IPython脚本在浏览器中⽣成可视化图表和统计信息。
开发流程
1.设计模型:根据需求在已有框架中设计新的模型(Thermal中的IPA),或者设计⼀个全新的功耗模型(如EAS)。⽬前阶段主要是跟踪追随现有功耗模型。
2.内核实现:基于之前功耗模型,在内核中代码实现。
3.验证环境:建⽴验证模型的环境,⼀⽅⾯要有量化Performance的⼯具,另⼀⽅⾯还需要量化Power的⼯具。
4.模型正确与否?:通过验证环境可以查看模型是否符合预期,如果不符合就重新进⾏设计。
5.调整模型:根据第4步验证结果,重新调整模型缺陷。
6.优化算法:验证算法是否⾼效,是否更有效的提升Performance,降低Power。
3. Android/Linux内核Power Management知识点
3.1 PM COMMON
《》从更⾼的层次介绍了电源管理,供电(PowerSupply),电池设备还需要充电(Charger),设备运⾏需要时钟(Clock),所在的电源域(PowerDomain),不同电压调节器(Regulator),调频调压(DVFS)以及睡眠唤醒(Suspend),保证功耗服务质量的QoS等等。
传统的粗粒度《》关注关机、重启、睡眠、冬眠(Hibernate)。
重启、关机有着相似的《》。
设备的功耗管理遵循着统⼀的《》,bus_type/device_driver/class/device中都嵌⼊了dev_pm_ops 。
3.2 SUSPEND
suspend能提供最深层次的省电,对外接⼝是/sys/power/state,⼀般由⽤户空间触发。suspend、wakeup、hibernate、sleep、str、str等等概念容易混淆,《》对其进⾏了区分,并架构上以及sysfs进⾏了介绍。
往/sys/power/state写⼊mem可以触发《》,suspend流程有着明晰的划分:PM Core-->Device PM-->syscore-->machine,同样的resume有着对应的阶段,但是顺序是反过来的。
《》和suspend有着明显的区别,hibernate则是将本应保存到RAM中的内容保存到了存储设备上了,可以更加省电。
linux下的sleep函数
对suspend的优化,因为其涉及到进程冻结、脏数据回写、各种外设的suspend、CPU等等内容,很容易引⼊问题,需要将其流程细分。
将suspend流程划分为不同phase,尤其Device相关需要在进⾏细分。⽽且基于Function call graph,甚⾄可以细节到每个函数执⾏时间。基本上达到了像素级的优化。
suspend的⼯具《》以及基于此的优化实例《》,详细介绍了⼯具和如何使⽤。
基于以上analyze_suspend.py思想,重新写了个简单的分析⼯具(TBC).
内核节点:
/sys/power/state
/sys/kernel/debug/tracing/events/power/suspend_resume
/sys/kernel/debug/suspend_stats
3.3 WAKEUP EVENT
具备唤醒功能的设备被称为wakeup source,它产⽣的唤醒时间被称为wakeup events。
《》介绍了Linux内核wakeup events框架,它也是wakelock、wakeup count以及autosleep的基础。
《》主要⽤于suspend同步,《》提供了内核和⽤户空间的wake lock。
《》受⽤户触发将suspend操作放⼊有序队列autosleep_wq。
内核节点:
/sys/kernel/debug/tracing/events/power/wakeup_source_*
/sys/kernel/debug/wakeup_sources
3.4 RUNTIME PM
设备影响功耗的⾏为《》,主要有是否具备唤醒能⼒,设备wakelock阻⽌系统进⼊唤醒的能⼒,从《》看,驱动相关的功耗⾏为包括suspend/resume/shutdown/poweroff/rumtime,传统的suspend/resume逐渐被抛弃,《》的runtime_suspend/runtime_resume/runtime_idle 更加灵活⾼效。
设备的RPM和cpuidle的深睡结合,功耗⽐较接近suspend了。
内核节点:
/sys/kernel/debug/tracing/events/rpm
3.5 CPUIDLE
CPU⽆事可做时会进⼊idle进程,cpu_idle是cpuidle进程的主循环,cpuidle_idle_call是⼊⼝点。《》对cpuidle基本功能和架构做了介绍,然后《》从cpuidle使⽤者kernel sched⾓度进⾏分析,同时介绍了对cpuidle device/driver/governor是如何管理的以及sysfs节点。
cpuidle device是⼀种虚拟的设备,《》提供了CPU⽀持的不同cpuidle状态以及进⼊状态的驱动。cpuidle⽀持不同种类的状态,如何根据当前情况进⼊不同状态呢》《》就是作出这种选的主题。可以说cpuidle governor是决策机构,cpuidle driver是执⾏机构,cpuidle core提供了触发点以及不同参数配置接⼝。
那么关于CPUIDLE我们能做什么呢?
重点在于governor和driver,driver提供的状态越多,cpuidle在节省功耗和QoS之间的选择就会越丰富;
governor主要有menu和ladder,顾名思义,menu可以根据需要直接跳转状态,⽽ladder需要⼀级⼀级的爬。
cpuidle提供了进⼊不同状态的Trace,可以通过分析其timeline,查看进⼊的状态。
内核节点:
/sys/devices/system/cpu/cpuidle
/sys/kernel/debug/tracing/events/power/cpu_idle
3.6 CPU OPS/HOTPLUG
针对SMP,在cpuidle和cpufreq之间还存在⼀种低功耗技术cpu的热插拔。在《》中,动态关闭不需要的不需要的CPU核,也可以达到节省功耗的⽬的。
了解《》才能更有针对性的进⾏hotplug。
在ARM体检架构下,针对CPU的suspend/idle等操作封装在《》,CUP的状态有online/active/present/possible,每个CPU的online节点是《》的操作接⼝。
内核节点:
/sys/devices/system/cpu/online
/sys/devices/system/cpu/offline
/sys/kernel/debug/tracing/events/cpuhp
3.7 CPUFREQ
cpufreq也称作DVFS,《》定义了不同的Voltage和Frequency的组合。
《》从架构上介绍了cpufreq是如何运作过的,介绍了core/driver/governor的关系,封装了cpufreq_driver、cpufreq_policy和
cpufreq_governor。《》提供了driver/policy/governor三者之间框架,同时通过sysfs向上提供了接⼝。
《》是调频的执⾏者,跟具体的架构芯⽚有关,特别的针对ARM的bL有《》。
《》作为调频调压的策略制定者,有很多种(performance/powersave/userspace/ondemand/interactive),需要根据实际情况选择。
另⼀系列(DroidPhone)关于cpufreq的⽂章,
《》
《》
《》
内核节点:
/sys/devices/system/cpu/cpufreq
/sys/kernel/debug/tracing/events/power/cpu_frequency
3.8 THERMAL
⾼功耗会带来温度问题,在达到⼀定温度的时候需要降低功耗。在散热和功耗消耗量之间有⼀个平衡点,在此功耗量,稳定基本保持稳定,同时不会对设备造成伤害。
《》就是⽤来处理这类事情的,thermal governor(IPA/stepwise)是决策者,thermal cooling是执⾏者。
在PC上有风扇,但是在嵌⼊式设备上只能通过降低功耗(主要是通过DVFS)来达到降低温度的⽬的。
《》是其中⼀种governor,它的核⼼是PID控制器。
内核节点:
/sys/class/thermal
/sys/kernel/debug/tracing/events/thermal
/sys/kernel/debug/tracing/events/thermal_power_allocator
3.9 CLOCK
《》是⽤来管理Clock资源的⼦系统。对其它dirver提供clocks通⽤API;从DT中解析出clock tree关系;不同类型的clock器件;clock设置主要内容包括enable/disable clock、设置clock频率、选择clock parent等。
《》介绍了如何编写clock driver,clock分类有fixed rate clock、gate clock、divider clock、mux clock、fixed factor clock、coposite clock。
《》从clock consumer和clock provider两个⾓度介绍内核是如何管理clock资源的,以及driver是怎么使⽤clock资源的。
《》总体介绍了common clock framework,从DT中获取clock provider、consumer以及common clock framework相关配置。Clock driver作为provider,其它设备作为consumer,两者通过common clock framework联系在⼀起。
内核节点:
/sys/kernel/debug/clk
/sys/kernel/debug/tracing/events/clk
/sys/kernel/debug/tracing/events/power/clock_*
3.10 PM QOS
PM的主要功能就是节省功耗,同时会付出⼀定性能代价。PM QoS的存在就是为了保证采取功耗措施之前,保证性能(延时、吞吐量)。
《》将整个框架分为核⼼QoS Framework、QoS Requestors(应⽤、GPU、Flash等驱动需要系统满⾜⼀定条件)、QoS
Requestee(cpuidle、RPM、PM Domain获取各种限制,确保⾃⾝⾏为满⾜限制)。
限制constrain分为2类:(1)系统级,包括cpu/dma latency、network latency、network throughput、memory bandwith;(2)设备级,包括从低功耗状态的resume latency、active状态latency和⼀些QoS flag。
《》负责系统级QoS管理。
《》负责per-device的QoS管理。
内核节点:
/sys/kernel/debug/pm_qos
/sys/kernel/debug/tracing/events/power/pm_qos*
/sys/kernel/debug/tracing/events/power/dev_pm_qos*
3.11 Power Domain
《》芯⽚设计往往根据不同功能或者不同电压将供电分为不同区域,即电源域。
这样系统运⾏过程中,可以根据需求动态开关某⼀电源域,已达到节省功耗的⽬的。
电源域框架包括使⽤者、提供者以及框架实现。
内核节点:
/sys/kernel/debug/tracing/events/power/power_domain_target
/sys/kernel/debug/pm_genpd/pm_genpd_summary
3.12 REGULATOR
Regulator包括voltage regulator和current regulator,可以⾃动维持很定电压/电流的输出。
《》介绍了Regulator框架,主要进⾏电压/电流最⼤最⼩值设置、开关等操作。Regulator框架向内核其它driver提供API⽤以控制电压电流输出,同时提供了实现⾃⾝driver的接⼝。
《》介绍了⼀个Regulator驱动实例。
内核节点:
/sys/class/regulator
/sys/kernel/debug/tracing/events/regulator
/sys/kernel/debug/regulator
3.13 POWER SUPPLY
Power Supply是供电设备的意思,为系统运⾏供电,包括电池设备、USB Charger、DC Charger。
《》对供电设备抽象形成struct power_supply,同时提供通过API⽤于编写不同供电设备驱动,向⽤户控件提供sysfs。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。