Linux下Power Management开发总结

本文作为一个提纲挈领的介绍性文档,后面会以此展开,逐渐丰富。

1. 前言

在 《开发流程》中介绍了PM开发的一般流程,重点是好的模型、简单有效的接口参数、可量化的测试环境以及可独性强的输出。

 

内核中功耗开发无论是新模型开发还是已有模型的调优,都需要了解现有的框架,遵循已有框架,简单有效的修改。这就需要了解《Android/Linux内核Power Management知识点》,关于Linux省电,从开机-->运行-->suspend-->关机这四种状态,开机/关机不太受关注,但是足够快也是省电的一种。

在进入细节之前,了解一下Linux中PM框架(PM COMMON)有助于下面学习。

suspend(SUSPEND)是一种深层次的省电,运行态情况下省电就八仙过海各显神通了。如果将电流曲线以timeline形式画出,功耗就是曲线覆盖的阴影面积了。一个任务来看,面积越小越好,当然时间也要满足需求。

suspend是系统级省电,涉及到各外设、Memory、CPU等等各种设备,总之是尽量关闭。只保留不能断电部分用于唤醒系统,以及系统恢复,比如外设唤醒中断、RAM Retention等。suspend本身也有不同种类,mem/standby/hibernation。大部分使用的还是mem,即suspend to ram。此时内核处于冻结状态(PROCESS FREEZE),系统tick停止,只有中断将其从睡眠唤醒才会去处理任务。

在系统运行过程中省电,则要复杂多变多了。对于CPU在工作是根据负载动态调频调压(CPUFREQ),没有工作处理的时候进入IDLE(CPUIDLE),更进一步在多核情况下CPU都可以被热插拔(CPU HOTPLUG);对于各种其他外设可以根据是否被使用而动态关闭(RUNTIME PM)。当然这些调节都要保证性能的输出(PM QoS)。

在系统运行过程中,高温可能导致设别损坏,因此根据温度来分配功耗也是一门必要手段(THERMAL)。

当然省电也离不开一些基础功能比如时钟控制(CLOCK)、供电开关(REGULATOR)、电源域划分(POWER DOMAIN),以及内核和应用都会用到的睡眠锁、唤醒源、唤醒事件都可以归到唤醒事件框架中(WAKEUP EVENT)。

系统的供电是使用AC还是电池,备抽象成POWER SUPPLY

 

工欲善其事,必先利其器。没有一个好的工具环境,去量化,只会一抹黑,如何验证模型正确与否?如何确定参数是否调优?《开发工具介绍》中介绍了ARM开源的两款工具Workload Automation和LISA,以及一些自己开发的工具集。

 

在了解开发对象和有了工具之后,当然要去试一试了。《优化实战记录》中详细记录的工具的使用、优化流程和结果。

 

在文章的结尾,对一些其相关点进行了罗列与总结《功耗知识点补充》。

2. 开发流程

针对一个PM feature进行开发,设计模型是第一步。模型设计好之后,还要保留参数接口,可以基于这些参数针对特殊个体进行优化。

建立一个可以快速迭代、准确可靠、可量化的验证环境尤其重要。一方面可以验证设计的模型是否有效、正确;另一方面还可以调整找到最适合的参数。

针对嵌入式设备来说,最主要的是达到性能和功耗的平衡:在满足性能要求的前提下,尽量降低功耗。

这就涉及到如何去量化性能(Performance)和功耗(Power)。

量化功耗比较简单,可以通过Power Monitor在测量点获得数据(测量点的确定很重要!);量化性能就比较复杂了,针对不同的功能模块,需要不同的性能分析工具。

另外,针对不同的模块,可能需要产生特定的workload。

最后,可读性强的统计信息或者可视化图表也更有利于得出分析结果。

 

以LISA为例,可以使用workload rt-app产生特定调度侧率,运行时间,运行在特定CPU上的线程,保证运行环境一致。

通过devlib可以获得测试过程中的Power Monitor数据。

然后通过IPython脚本在浏览器中生成可视化图表和统计信息。

Linux下Power Management开发总结_第1张图片

开发流程

 

1.设计模型:根据需求在已有框架中设计新的模型(Thermal中的IPA),或者设计一个全新的功耗模型(如EAS)。目前阶段主要是跟踪追随现有功耗模型。

2.内核实现:基于之前功耗模型,在内核中代码实现。

3.验证环境:建立验证模型的环境,一方面要有量化Performance的工具,另一方面还需要量化Power的工具。

4.模型正确与否?:通过验证环境可以查看模型是否符合预期,如果不符合就重新进行设计。

5.调整模型:根据第4步验证结果,重新调整模型缺陷。

6.优化算法:验证算法是否高效,是否更有效的提升Performance,降低Power。

3. Android/Linux内核Power Management知识点

3.1 PM COMMON

Linux电源管理(1)_整体架构》从更高的层次介绍了电源管理,供电(PowerSupply),电池设备还需要充电(Charger),设备运行需要时钟(Clock),所在的电源域(PowerDomain),不同电压调节器(Regulator),调频调压(DVFS)以及睡眠唤醒(Suspend),保证功耗服务质量的QoS等等。

传统的粗粒度《Linux电源管理(2)_Generic PM之基本概念和软件架构》关注关机、重启、睡眠、冬眠(Hibernate)。

重启、关机有着相似的《Linux电源管理(3)_Generic PM之Reboot过程》。

设备的功耗管理遵循着统一的《Linux电源管理(4)_Power Management Interface》,bus_type/device_driver/class/device中都嵌入了dev_pm_ops 。

 

3.2 SUSPEND

suspend能提供最深层次的省电,对外接口是/sys/power/state,一般由用户空间触发。suspend、wakeup、hibernate、sleep、str、str等等概念容易混淆,《Linux电源管理(5)_Hibernate和Sleep功能介绍》对其进行了区分,并架构上以及sysfs进行了介绍。

往/sys/power/state写入mem可以触发《Linux电源管理(6)_Generic PM之Suspend功能》,suspend流程有着明晰的划分:PM Core-->Device PM-->syscore-->machine,同样的resume有着对应的阶段,但是顺序是反过来的。

Linux电源管理(12)_Hibernate功能》和suspend有着明显的区别,hibernate则是将本应保存到RAM中的内容保存到了存储设备上了,可以更加省电。


 Linux下Power Management开发总结_第2张图片对suspend的优化,因为其涉及到进程冻结、脏数据回写、各种外设的suspend、CPU等等内容,很容易引入问题,需要将其流程细分。

将suspend流程划分为不同phase,尤其Device相关需要在进行细分。而且基于Function call graph,甚至可以细节到每个函数执行时间。基本上达到了像素级的优化。

suspend的工具《Linux suspend分析优化工具——analyze_suspend.py》以及基于此的优化实例《Suspend to RAM和Suspend to Idle分析,以及在HiKey上性能对比》,详细介绍了工具和如何使用。

基于以上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电源管理(7)_Wakeup events framework介绍了Linux内核wakeup events框架,它也是wakelock、wakeup count以及autosleep的基础。

Linux电源管理(8)_Wakeup count功能主要用于suspend同步,Linux电源管理(9)_wakelocks提供了内核和用户空间的wake lock。

Linux电源管理(10)_autosleep受用户触发将suspend操作放入有序队列autosleep_wq。

 

内核节点:

/sys/kernel/debug/tracing/events/power/wakeup_source_*

/sys/kernel/debug/wakeup_sources

 

3.4 RUNTIME PM

设备影响功耗的行为《Linux电源管理(13)_Driver的电源管理》,主要有是否具备唤醒能力,设备wakelock阻止系统进入唤醒的能力,从《Linux电源管理(14)_从设备驱动的角度看电源管理》看,驱动相关的功耗行为包括suspend/resume/shutdown/poweroff/rumtime,传统的suspend/resume逐渐被抛弃,《Linux电源管理(11)_Runtime PM之功能描述》的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是入口点。《Linux cpuidle framework(1)_概述和软件架构》对cpuidle基本功能和架构做了介绍,然后《Linux cpuidle framework(2)_cpuidle core》从cpuidle使用者kernel sched角度进行分析,同时介绍了对cpuidle device/driver/governor是如何管理的以及sysfs节点。

cpuidle device是一种虚拟的设备,《Linux cpuidle framework(3)_ARM64 generic CPU idle driver》提供了CPU支持的不同cpuidle状态以及进入状态的驱动。cpuidle支持不同种类的状态,如何根据当前情况进入不同状态呢》《Linux cpuidle framework(4)_menu governor》就是作出这种选的主题。可以说cpuidle governor是决策机构,cpuidle driver是执行机构,cpuidle core提供了触发点以及不同参数配置接口。

那么关于CPUIDLE我们能做什么呢?

重点在于governor和driver,driver提供的状态越多,cpuidle在节省功耗和QoS之间的选择就会越丰富;

governor主要有menu和ladder,顾名思义,menu可以根据需要直接跳转状态,而ladder需要一级一级的爬。


Linux下Power Management开发总结_第3张图片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的热插拔。在《Linux CPU core的电源管理(1)_概述》中,动态关闭不需要的不需要的CPU核,也可以达到节省功耗的目的。

了解《Linux CPU core的电源管理(2)_cpu topology》才能更有针对性的进行hotplug。

在ARM体检架构下,针对CPU的suspend/idle等操作封装在《Linux CPU core的电源管理(3)_cpu ops》,CUP的状态有online/active/present/possible,每个CPU的online节点是《Linux CPU core的电源管理(5)_cpu control及cpu hotplug》的操作接口。 

内核节点:

/sys/devices/system/cpu/online

/sys/devices/system/cpu/offline

/sys/kernel/debug/tracing/events/cpuhp

 

3.7 CPUFREQ

cpufreq也称作DVFS,《Linux电源管理(15)_PM OPP Interface》定义了不同的Voltage和Frequency的组合。

linux cpufreq framework(1)_概述》从架构上介绍了cpufreq是如何运作过的,介绍了core/driver/governor的关系,封装了cpufreq_driver、cpufreq_policy和cpufreq_governor。《linux cpufreq framework(3)_cpufreq core》提供了driver/policy/governor三者之间框架,同时通过sysfs向上提供了接口。

Linux cpufreq framework(2)_cpufreq driver》是调频的执行者,跟具体的架构芯片有关,特别的针对ARM的bL有《linux cpufreq framework(5)_ARM big Little driver》。

linux cpufreq framework(4)_cpufreq governor》作为调频调压的策略制定者,有很多种(performance/powersave/userspace/ondemand/interactive),需要根据实际情况选择。

 

 另一系列(DroidPhone)关于cpufreq的文章,

《Linux动态频率调节系统CPUFreq之一:概述》

《Linux动态频率调节系统CPUFreq之二:核心(core)架构与API》

《Linux动态频率调节系统CPUFreq之三:governor》 

 

内核节点:

/sys/devices/system/cpu/cpufreq

/sys/kernel/debug/tracing/events/power/cpu_frequency

3.8 THERMAL

高功耗会带来温度问题,在达到一定温度的时候需要降低功耗。在散热和功耗消耗量之间有一个平衡点,在此功耗量,稳定基本保持稳定,同时不会对设备造成伤害。

Android/Linux Thermal框架分析及其Governor对比》就是用来处理这类事情的,thermal governor(IPA/stepwise)是决策者,thermal cooling是执行者。

在PC上有风扇,但是在嵌入式设备上只能通过降低功耗(主要是通过DVFS)来达到降低温度的目的。《Android/Linux Thermal Governor之IPA分析与使用》是其中一种governor,它的核心是PID控制器。

 

内核节点:

/sys/class/thermal

/sys/kernel/debug/tracing/events/thermal

/sys/kernel/debug/tracing/events/thermal_power_allocator

 

3.9 CLOCK

Linux common clock framework(1)_概述是用来管理Clock资源的子系统。对其它dirver提供clocks通用API;从DT中解析出clock tree关系;不同类型的clock器件;clock设置主要内容包括enable/disable clock、设置clock频率、选择clock parent等。

Linux common clock framework(2)_clock provider介绍了如何编写clock driver,clock分类有fixed rate clock、gate clock、divider clock、mux clock、fixed factor clock、coposite clock。

Linux common clock framework(3)_实现逻辑分析从clock consumer和clock provider两个角度介绍内核是如何管理clock资源的,以及driver是怎么使用clock资源的。

Common Clock Framework系统结构总体介绍了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的存在就是为了保证采取功耗措施之前,保证性能(延时、吞吐量)。

Linux PM QoS framework(1)_概述和软件架构将整个框架分为核心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。

Linux PM QoS framework(2)_PM QoS class负责系统级QoS管理。

Linux PM QoS framework(3)_per-device PM 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

Linux PM domain framework(1)_概述和使用流程芯片设计往往根据不同功能或者不同电压将供电分为不同区域,即电源域。

这样系统运行过程中,可以根据需求动态开关某一电源域,已达到节省功耗的目的。

电源域框架包括使用者、提供者以及框架实现。

 

内核节点:

/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,可以自动维持很定电压/电流的输出。

Linux Regulator Framework(1)_概述介绍了Regulator框架,主要进行电压/电流最大最小值设置、开关等操作。Regulator框架向内核其它driver提供API用以控制电压电流输出,同时提供了实现自身driver的接口。

Linux Regulator Framework(2)_regulator 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。

Linux power supply class(1)_软件架构及API汇整对供电设备抽象形成struct power_supply,同时提供通过API用于编写不同供电设备驱动,向用户控件提供sysfs。

 

内核节点:

/sys/class/power_supply

 

 3.14 PROCESS FREEZE

在进入suspend之前,需要将所有用户进程和内核线程暂停,这就需要《Linux进程冻结技术》。在对进程冻结,使其处于可控状态后才可以进行设备suspend操作以及CPU关闭等。

  

4. 开发工具介绍

《Workload Automation分析及其使用》

分析了WA的框架以及其使用,重点是基于WA的框架进行二次开发。从工具名称就可以知道此工具是自动化产生负荷,然后对测试结果做post-processing。

首先为什么要有workload概念,由于测试对象不同,需要特定的用例,只有通过特殊的工具,比如rt-app能产生一定CPU load、不同数量、不同优先级、不同调度策略的进程,这种灵活性是手工无法达到的。

同时由于自动化,避免了认为带来的不确定性。WA的框架,也非常适合二次开发。不同待测设备,增加device即可;开发新的负荷,增加workload;增加测量仪表,增加instrument;需要新的手段分析数据,增加result_processor。

同时由于自动化,极大的提高了开发测试效率,更加敏捷。

 

《LISA介绍及其使用方法》

 

《Linux Power Management Debug》

 收集了网上一些关于功耗调试的方法工具,有很多开源好东东值得拥有。

 

《Linux下功耗测试开发初探》

由于功耗曲线和内核行为无法对应,开发测试中多靠经验判断。如果能将实际功耗和内核行为对应,那么将极大提高功耗Debug的能力。

 此工具也着重于此痛点,对功耗曲线进行highlight,并且标注消耗量和平均电流。然后基于同样timeline显示内核行为irq、wakelock、cpuidle、cpufreq等等内核行为。可以方便查看异常功耗时的内核行为。

 

《Suspend分析工具analyze_suspend,及其WA自动化》 

 

《数据分析之---Python可视化工具》

对测试数据进行分析,并将其可视化是Python的强项,数据分析的Pandas/NumPy,可视化的matplotlib/bokeh等等。

将这些工具用于问题分析,以及优化调试非常有效。

5. 优化实战记录

5.1 Suspend分析与优化

《Suspend to RAM和Suspend to Idle分析,以及在HiKey上性能对比》

《cpu_ops、suspend_ops、arm_idle_driver以及machine_restart/machine_power_off到底层PSCI Firmware分析》

 5.2 开机时间优化

关于开机时间的优化,分为内核和用户空间两部分。内核的优化依赖于dmesg(analyze_boot.py),用户空间的优化依赖于busybox附带的bootchart(pybootchartgui.py),Ubuntu等使用systemd-analyze更加简单。

《Android/Linux boot time分析优化》

《Busybox下Bootchart的使用》

《一个Linux系统开机时间优化实例》

 一些在Linaro WiKi上写的文档:

《How-To-PM-debugging》

《system-suspend》

6. 功耗知识点补充

《DDR相关的低功耗技术之PASR、TCSR、DPD》

你可能感兴趣的:(Linux下Power Management开发总结)